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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With