Custom UserDetailService circular reference with GlobalMethodSecurity - java

I'm trying to convert our security.xml to JavaConfig
**
* <security:global-method-security
secured-annotations="enabled"
jsr250-annotations="enabled"
access-decision-manager-ref="accessDecisionManager">
</security:global-method-security>
*/
#Configuration
#EnableGlobalMethodSecurity( jsr250Enabled = true, securedEnabled = true )
public class SecurityConfig
{
private UserDetailsService userDetailsService;
/**
* <bean id="accessDecisionManager"
class="org.springframework.security.access.vote.AffirmativeBased">
<constructor-arg>
<list>
<bean class="com.myapp.security.access.voter.MyAppRoleVoter">
<property name="rolePrefix" value="" />
</bean>
<bean class="org.springframework.security.access.vote.AuthenticatedVoter" />
</list>
</constructor-arg>
</bean>
*/
#Bean
AccessDecisionManager accessDecisionManager( ) {
return new AffirmativeBased( Collections.singletonList( new MyAppRoleVoter() ) );
}
/**
* <security:authentication-manager alias="authenticationManager">
<security:authentication-provider user-service-ref="clientDetailsUserService"/>
<security:authentication-provider user-service-ref="principalService">
<security:password-encoder ref="passwordEncoder" />
</security:authentication-provider>
</security:authentication-manager>
*/
#Autowired
void configureGlobal(
final AuthenticationManagerBuilder auth,
#Qualifier( PasswordEncryptionConfig.PASSWORD_ENCODER ) final PasswordEncoder passwordEncoder
) throws Exception {
auth.userDetailsService( userDetailsService ).passwordEncoder( passwordEncoder );
}
#Autowired
public void setUserDetailsService(
#Qualifier( PrincipalService.BEAN_ID ) final UserDetailsService userDetailsService )
{
this.userDetailsService = userDetailsService;
}
}
This exception isn't particularly surprising
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void com.myapp.config.SecurityConfig.setUserDetailsService(org.springframework.security.core.userdetails.UserDetailsService); nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'methodSecurityInterceptor': Requested bean is currently in creation: Is there an unresolvable circular reference?
How can I write my javaconfig so that it does the same thing as the previous XML? (Update: at the time of this writing this is occurring in Spring Security 4.0.4 on Platform BOM 2.0.5)

Related

Authenticationmanager java config

What is the equivalent in java config of this XML authentication-manager config?
<authentication-manager alias="authenticationManager"> ... </authentication-manager>
What i need exactly is convert this xml config to java config :
`<security:authentication-manager alias="authenticationManagerLdap">
<security:authentication-provider ref="ldapActiveDirectoryAuthProvider"/>
</security:authentication-manager>
<bean id="ldapActiveDirectoryAuthProvider" class="ma.gov.adii.beans.AuthenticationAD">
<constructor-arg value="adii.gov.ma"/>
<constructor-arg value="ldap://addouane.adii.gov.ma:389/"/>
<property name="convertSubErrorCodesToExceptions" value="true" />
<property name="userDetailsContextMapper" ref="manageLoginService" />
</bean>`
My login clas is like this :
public class LoginMBean implements Serializable { #Autowired private AuthenticationManager authenticationManagerLdap;
Thanks
THE ANSWER IS LIKE THIS :
#Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
#Autowired
void registerProvider(AuthenticationManagerBuilder authLdap) {
authLdap.authenticationProvider(ldapActiveDirectoryAuthProvider());
}

Spring Security: How to inject the AuthenticationManager in a controller? [duplicate]

I'm using Spring Security 3.2 and Spring 4.0.1
I'm working on converting an xml config into a Java config. When I annotate AuthenticationManager with #Autowired in my Filter, I'm getting an exception
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.security.authentication.AuthenticationManager] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
I've tried injecting AuthenticationManagerFactoryBean but that also fails with a similar exception.
Here is the XML configuration I'm working from
<?xml version="1.0" encoding="UTF-8"?> <beans ...>
<security:authentication-manager id="authenticationManager">
<security:authentication-provider user-service-ref="userDao">
<security:password-encoder ref="passwordEncoder"/>
</security:authentication-provider>
</security:authentication-manager>
<security:http
realm="Protected API"
use-expressions="true"
auto-config="false"
create-session="stateless"
entry-point-ref="unauthorizedEntryPoint"
authentication-manager-ref="authenticationManager">
<security:access-denied-handler ref="accessDeniedHandler"/>
<security:custom-filter ref="tokenAuthenticationProcessingFilter" position="FORM_LOGIN_FILTER"/>
<security:custom-filter ref="tokenFilter" position="REMEMBER_ME_FILTER"/>
<security:intercept-url method="GET" pattern="/rest/news/**" access="hasRole('user')"/>
<security:intercept-url method="PUT" pattern="/rest/news/**" access="hasRole('admin')"/>
<security:intercept-url method="POST" pattern="/rest/news/**" access="hasRole('admin')"/>
<security:intercept-url method="DELETE" pattern="/rest/news/**" access="hasRole('admin')"/>
</security:http>
<bean class="com.unsubcentral.security.TokenAuthenticationProcessingFilter"
id="tokenAuthenticationProcessingFilter">
<constructor-arg value="/rest/user/authenticate"/>
<property name="authenticationManager" ref="authenticationManager"/>
<property name="authenticationSuccessHandler" ref="authenticationSuccessHandler"/>
<property name="authenticationFailureHandler" ref="authenticationFailureHandler"/>
</bean>
</beans>
Here is the Java Config I'm attempting
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Autowired
private PasswordEncoder passwordEncoder;
#Autowired
private AuthenticationEntryPoint authenticationEntryPoint;
#Autowired
private AccessDeniedHandler accessDeniedHandler;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint)
.accessDeniedHandler(accessDeniedHandler)
.and();
//TODO: Custom Filters
}
}
And this is the Custom Filter class. The line giving me trouble is the setter for AuthenticationManager
#Component
public class TokenAuthenticationProcessingFilter extends AbstractAuthenticationProcessingFilter {
#Autowired
public TokenAuthenticationProcessingFilter(#Value("/rest/useAuthenticationManagerr/authenticate") String defaultFilterProcessesUrl) {
super(defaultFilterProcessesUrl);
}
#Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
...
}
private String obtainPassword(HttpServletRequest request) {
return request.getParameter("password");
}
private String obtainUsername(HttpServletRequest request) {
return request.getParameter("username");
}
#Autowired
#Override
public void setAuthenticationManager(AuthenticationManager authenticationManager) {
super.setAuthenticationManager(authenticationManager);
}
#Autowired
#Override
public void setAuthenticationSuccessHandler(AuthenticationSuccessHandler successHandler) {
super.setAuthenticationSuccessHandler(successHandler);
}
#Autowired
#Override
public void setAuthenticationFailureHandler(AuthenticationFailureHandler failureHandler) {
super.setAuthenticationFailureHandler(failureHandler);
}
}
Override method authenticationManagerBean in WebSecurityConfigurerAdapter to expose the AuthenticationManager built using configure(AuthenticationManagerBuilder) as a Spring bean:
For example:
#Bean(name = BeanIds.AUTHENTICATION_MANAGER)
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
In addition to what Angular University said above you may want to use #Import to aggregate #Configuration classes to the other class (AuthenticationController in my case) :
#Import(SecurityConfig.class)
#RestController
public class AuthenticationController {
#Autowired
private AuthenticationManager authenticationManager;
//some logic
}
Spring doc about Aggregating #Configuration classes with #Import: link
When I #Bean'ed AuthenticationManager and #Autowired it in same class then needed to activate circular references but that is rather as for CDI.

WebSecurityConfig Java equivalent for spring LDAP authentication done with spring-security.xml

I implemented the LDAP authentication and authorization using Spring Security in my project. I configured the spring-security.xml and got it running. I am trying to do the same using Java (WebSecurityConfig.java). Can someone guide me on how to do this?
Here is my spring-security.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.2.xsd">
<!-- This is where we configure Spring-Security -->
<security:http auto-config="true" use-expressions="true" >
<security:intercept-url pattern="/main/common" access="hasRole('role.xyz.WebAdmin')"/>
<security:intercept-url pattern="/admincare" access="hasRole('role.xyz.WebAdmin')"/>
<security:form-login
login-page="/auth/login"
authentication-failure-url="/auth/login?error=true"
default-target-url="/main/common"/>
<security:logout
invalidate-session="true"
logout-success-url="/auth/login"
logout-url="/auth/logout"/>
</security:http>
<security:authentication-manager>
<security:authentication-provider ref="ldapAuthProvider" />
</security:authentication-manager>
<bean id="ldapAuthProvider" class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
<constructor-arg name="authenticator">
<bean class="org.springframework.security.ldap.authentication.BindAuthenticator">
<constructor-arg ref="ldapContext" />
<property name="userSearch">
<bean class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
<constructor-arg name="searchBase" value="" />
<constructor-arg name="searchFilter" value="(&(uid={0})(objectclass=person)(ums-account-state=OK))" />
<constructor-arg name="contextSource" ref="ldapContext" />
</bean>
</property>
</bean>
</constructor-arg>
<constructor-arg>
<bean class="com.gemalto.mobileid.service.UmsLdapAuthoritiesPopulator">
<constructor-arg ref="ldapContext"/>
</bean>
</constructor-arg>
</bean>
<security:ldap-server id="ldapContext" url="ldap://aaa:54389/dc=xxx.com" manager-dn="bbb" manager-password="ccc" />
</beans>
Now, if I want to do same in the JAVA style (in WebSecurityConfig.java) and get rid of the XML, how do I do? I am not so familiar with the APIs provided for this. I started it this way:
public ActiveDirectoryLdapAuthenticationProvider activeDirectoryLdapAuthenticationProvider() {
ActiveDirectoryLdapAuthenticationProvider provider = new ActiveDirectoryLdapAuthenticationProvider("", "ldap://aaa:54389/dc=xxx.com");
provider.setConvertSubErrorCodesToExceptions(true);
provider.setUseAuthenticationRequestCredentials(true);
provider.setUseAuthenticationRequestCredentials(true);
return provider;
}
#Bean
public LoggerListener loggerListener() {
return new LoggerListener();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(activeDirectoryLdapAuthenticationProvider());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
// Configuration for Redirects, Login-Page and stuff
http
.authorizeRequests()
.antMatchers("/admincare").authenticated()
.and()
.formLogin();
//.loginPage("/auth/login")
//.permitAll();
}
I am not sure how to set the rest of the parameters (as done in XML) in this Java code for the WebSecurityConfig. Any help would be really appreciated
Pls try this :-
#Bean
public BaseLdapPathContextSource contextSource() {
DefaultSpringSecurityContextSource contextSource = new DefaultSpringSecurityContextSource("ldap://aaa:54389/dc=xxx.com");
contextSource.setUserDn("bbb");
contextSource.setPassword("ccc");
return contextSource;
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.ldapAuthentication()
.contextSource(contextSource())
.and()
.ldapAuthoritiesPopulator(new UmsLdapAuthoritiesPopulator(contextSource()))
.and()
.userSearchBase("").userSearchFilter("(&(uid={0})(objectclass=person)(ums-account-state=OK))");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/main/common**","/admincare**").hasRole("role.xyz.WebAdmin")
.and().formLogin().loginPage("/auth/login").failureUrl("/auth/login?error=true").defaultSuccessUrl("/main/common")
.and().logout().invalidateHttpSession(true).logoutSuccessUrl("/auth/login").logoutUrl("/auth/logout");
}

Spring OAuth2 "Full authentication is required to access this resource"

I'm trying to use Spring OAuth2 for my rest app.
But looks like I made a mistake and I can find where I did it.
The flow should be:
1. get token from /oauth/token with username and password
2. make request to /security with provided token
MethodSecurityConfig:
#Configuration
#EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
#Autowired
private SecurityConfiguration securityConfig;
#Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
return new OAuth2MethodSecurityExpressionHandler();
}
}
OAuth2ServerConfig:
#Configuration
public class OAuth2ServerConfig {
private static final String RESOURCE_ID = "nessnity";
#Configuration
#Order(10)
protected static class UiResourceConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.requestMatchers().antMatchers("/security")
.and()
.authorizeRequests()
.antMatchers("/security").access("hasRole('USER')");
}
}
#Configuration
#EnableResourceServer
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
#Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId(RESOURCE_ID);
}
#Override
public void configure(HttpSecurity http) throws Exception {
http
.requestMatchers().antMatchers("/security/")
.and()
.authorizeRequests()
.antMatchers("/security").access("#oauth2.hasScope('read')");
}
}
#Configuration
#EnableAuthorizationServer
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
#Autowired
private TokenStore tokenStore;
#Autowired
private UserApprovalHandler userApprovalHandler;
#Autowired
private AuthenticationManager authenticationManager;
#Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("my-client")
.resourceIds(RESOURCE_ID)
.authorizedGrantTypes("client_credentials")
.authorities("ROLE_CLIENT")
.scopes("read")
.secret("password")
.accessTokenValiditySeconds(60);
}
#Bean
public TokenStore tokenStore() {
return new InMemoryTokenStore();
}
#Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.tokenStore(tokenStore)
.userApprovalHandler(userApprovalHandler)
.authenticationManager(authenticationManager);
}
#Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.realm("sparklr2/client");
}
}
protected static class Stuff {
#Autowired
private ClientDetailsService clientDetailsService;
#Autowired
private TokenStore tokenStore;
#Bean
public ApprovalStore approvalStore() throws Exception {
TokenApprovalStore store = new TokenApprovalStore();
store.setTokenStore(tokenStore);
return store;
}
#Bean
#Lazy
#Scope(proxyMode=ScopedProxyMode.TARGET_CLASS)
public SparklrUserApprovalHandler userApprovalHandler() throws Exception {
SparklrUserApprovalHandler handler = new SparklrUserApprovalHandler();
handler.setApprovalStore(approvalStore());
handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService));
handler.setClientDetailsService(clientDetailsService);
handler.setUseApprovalStore(true);
return handler;
}
}
}
SecurityConfiguration:
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("root")
.password("password")
.roles("USER");
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/oauth/uncache_approvals", "/oauth/cache_approvals");
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().hasRole("USER");
}
}
Problem: when I tried to get token
curl --user root:password --data "grant_type=client_credentials" http://localhost:8080/oauth/token
I got message:
{"error":"invalid_client","error_description":"Bad client
credentials"}
The second question is how to pass username/password in the url params like /oauth/token?username=root&password=password ?
Thanks.
UPDATE
I decided to start from scratch and use xml configuration.
The following configuration works perfect:
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
xsi:schemaLocation="http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2-1.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<http pattern="/oauth/token" create-session="stateless"
authentication-manager-ref="authenticationManager"
xmlns="http://www.springframework.org/schema/security">
<intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY"/>
<anonymous enabled="false"/>
<http-basic entry-point-ref="clientAuthenticationEntryPoint"/>
<custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER"/>
<access-denied-handler ref="oauthAccessDeniedHandler"/>
</http>
<bean id="clientCredentialsTokenEndpointFilter"
class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
<property name="authenticationManager" ref="authenticationManager"/>
</bean>
<authentication-manager alias="authenticationManager"
xmlns="http://www.springframework.org/schema/security">
<authentication-provider user-service-ref="clientDetailsUserService"/>
</authentication-manager>
<bean id="clientDetailsUserService"
class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">
<constructor-arg ref="clientDetails"/>
</bean>
<bean id="clientDetails" class="com.nessnity.api.security.OAuthClienDetailsService">
<property name="id" value="testuser"/>
<property name="secretKey" value="secret" />
</bean>
<bean id="clientAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
<property name="realmName" value="springsec/client"/>
<property name="typeName" value="Basic"/>
</bean>
<bean id="oauthAccessDeniedHandler"
class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler"/>
<oauth:authorization-server
client-details-service-ref="clientDetails"
token-services-ref="tokenServices">
<oauth:authorization-code/>
<oauth:implicit/>
<oauth:refresh-token/>
<oauth:client-credentials/>
<oauth:password authentication-manager-ref="userAuthenticationManager"/>
</oauth:authorization-server>
<authentication-manager id="userAuthenticationManager"
xmlns="http://www.springframework.org/schema/security">
<authentication-provider ref="customUserAuthenticationProvider">
</authentication-provider>
</authentication-manager>
<bean id="customUserAuthenticationProvider"
class="com.nessnity.api.security.OAuthUserAuthenticationProvider">
</bean>
<bean id="tokenServices"
class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">
<property name="tokenStore" ref="tokenStore"/>
<property name="supportRefreshToken" value="true"/>
<property name="accessTokenValiditySeconds" value="900000000"/>
<property name="clientDetailsService" ref="clientDetails"/>
</bean>
<bean id="tokenStore"
class="org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore"/>
<bean id="oauthAuthenticationEntryPoint"
class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
</bean>
<http pattern="/resources/**" create-session="never"
entry-point-ref="oauthAuthenticationEntryPoint"
xmlns="http://www.springframework.org/schema/security">
<anonymous enabled="false"/>
<intercept-url pattern="/resources/**" method="GET"/>
<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER"/>
<access-denied-handler ref="oauthAccessDeniedHandler"/>
</http>
<oauth:resource-server id="resourceServerFilter"
resource-id="springsec" token-services-ref="tokenServices"/>
</beans>
I have faced similar for me it worked after doing the following change
In your AuthorizationServerConfiguration class replace
#Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.realm("sparklr2/client");
}
with the below code
#Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
//oauthServer.realm("sparklr2/client");
oauthServer.allowFormAuthenticationForClients();
}
and request should like
/oauth/token?grant_type=password&scope=read+write&client_id=yourclientId&client_secret=secret&username=userName&password=pwd
In your access token request you are using client credentials grant type. OAuth spec says that in case of client_credentials grant type you need to provide base64 encoded client_id:client_secret as Basic Authorization header.
For example if your client_id is google and client_secret is x23r-ss56-rfg8-6yt6, then you need to add these string as google:x23r-ss56-rfg8-6yt6, encode it using Base64 encoder and make request as
curl --header "Authorization: Basic <base64 encoded_string>" --data "grant_type=client_credentials" http://localhost:8080/oauth/token

How To Inject AuthenticationManager using Java Configuration in a Custom Filter

I'm using Spring Security 3.2 and Spring 4.0.1
I'm working on converting an xml config into a Java config. When I annotate AuthenticationManager with #Autowired in my Filter, I'm getting an exception
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.security.authentication.AuthenticationManager] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
I've tried injecting AuthenticationManagerFactoryBean but that also fails with a similar exception.
Here is the XML configuration I'm working from
<?xml version="1.0" encoding="UTF-8"?> <beans ...>
<security:authentication-manager id="authenticationManager">
<security:authentication-provider user-service-ref="userDao">
<security:password-encoder ref="passwordEncoder"/>
</security:authentication-provider>
</security:authentication-manager>
<security:http
realm="Protected API"
use-expressions="true"
auto-config="false"
create-session="stateless"
entry-point-ref="unauthorizedEntryPoint"
authentication-manager-ref="authenticationManager">
<security:access-denied-handler ref="accessDeniedHandler"/>
<security:custom-filter ref="tokenAuthenticationProcessingFilter" position="FORM_LOGIN_FILTER"/>
<security:custom-filter ref="tokenFilter" position="REMEMBER_ME_FILTER"/>
<security:intercept-url method="GET" pattern="/rest/news/**" access="hasRole('user')"/>
<security:intercept-url method="PUT" pattern="/rest/news/**" access="hasRole('admin')"/>
<security:intercept-url method="POST" pattern="/rest/news/**" access="hasRole('admin')"/>
<security:intercept-url method="DELETE" pattern="/rest/news/**" access="hasRole('admin')"/>
</security:http>
<bean class="com.unsubcentral.security.TokenAuthenticationProcessingFilter"
id="tokenAuthenticationProcessingFilter">
<constructor-arg value="/rest/user/authenticate"/>
<property name="authenticationManager" ref="authenticationManager"/>
<property name="authenticationSuccessHandler" ref="authenticationSuccessHandler"/>
<property name="authenticationFailureHandler" ref="authenticationFailureHandler"/>
</bean>
</beans>
Here is the Java Config I'm attempting
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsService userDetailsService;
#Autowired
private PasswordEncoder passwordEncoder;
#Autowired
private AuthenticationEntryPoint authenticationEntryPoint;
#Autowired
private AccessDeniedHandler accessDeniedHandler;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint)
.accessDeniedHandler(accessDeniedHandler)
.and();
//TODO: Custom Filters
}
}
And this is the Custom Filter class. The line giving me trouble is the setter for AuthenticationManager
#Component
public class TokenAuthenticationProcessingFilter extends AbstractAuthenticationProcessingFilter {
#Autowired
public TokenAuthenticationProcessingFilter(#Value("/rest/useAuthenticationManagerr/authenticate") String defaultFilterProcessesUrl) {
super(defaultFilterProcessesUrl);
}
#Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
...
}
private String obtainPassword(HttpServletRequest request) {
return request.getParameter("password");
}
private String obtainUsername(HttpServletRequest request) {
return request.getParameter("username");
}
#Autowired
#Override
public void setAuthenticationManager(AuthenticationManager authenticationManager) {
super.setAuthenticationManager(authenticationManager);
}
#Autowired
#Override
public void setAuthenticationSuccessHandler(AuthenticationSuccessHandler successHandler) {
super.setAuthenticationSuccessHandler(successHandler);
}
#Autowired
#Override
public void setAuthenticationFailureHandler(AuthenticationFailureHandler failureHandler) {
super.setAuthenticationFailureHandler(failureHandler);
}
}
Override method authenticationManagerBean in WebSecurityConfigurerAdapter to expose the AuthenticationManager built using configure(AuthenticationManagerBuilder) as a Spring bean:
For example:
#Bean(name = BeanIds.AUTHENTICATION_MANAGER)
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
In addition to what Angular University said above you may want to use #Import to aggregate #Configuration classes to the other class (AuthenticationController in my case) :
#Import(SecurityConfig.class)
#RestController
public class AuthenticationController {
#Autowired
private AuthenticationManager authenticationManager;
//some logic
}
Spring doc about Aggregating #Configuration classes with #Import: link
When I #Bean'ed AuthenticationManager and #Autowired it in same class then needed to activate circular references but that is rather as for CDI.

Categories