How To Inject AuthenticationManager using Java Configuration in a Custom Filter
Solution 1
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();
}
Solution 2
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
Comments
-
rince about 2 years
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 exceptionCaused 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); } }
-
Roger about 9 years@qxixp "to expose the AuthenticationManager built using configure(AuthenticationManagerBuilder) as a Spring bean"
-
qxixp about 9 years@Roger, why do we need to manually expose the AuthenticationManager?
-
Roger about 9 years@qxixp you can only Autowire a spring managed bean. If its not exposed as a bean, you cannot Autowire it.
-
searching9x about 8 yearsThe super method is not a Bean, then Override it and add Bean annotation.
-
Isthar about 7 yearsWhat really helped me of this answer is the "name = BeanIds.AUTHENTICATION_MANAGER". Without it, it doesn't work at least in my environment.
-
Dimitri Kopriwa over 6 yearsUsing this I can't login it create 401. But the same error I have in my test environment is gone. I also have 401 in my test environment.
-
Rick Slinkman over 5 yearsThanks, this worked for me when I had a StackOverflowException in this configuration today..
-
phxism almost 4 yearsthis way does not work for customized filter in spring security oauth2 ,
@Bean super.authenticationManagerBean()
like this will not build theClientDetailsUserDetailsService
andDaoAuthenticationProvider
it's different from the wayhttp.getSharedObject(AuthenticationManager.class)