How To Inject AuthenticationManager using Java Configuration in a Custom Filter

java, spring, spring-java-config, spring-security

Solution

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();
   }

Problem

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); } } ```

Original source

Related problems