How To Inject AuthenticationManager using Java Configuration in a Custom Filter

一曲冷凌霜 提交于 2019-11-26 02:29:40

问题


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

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


来源:https://stackoverflow.com/questions/21633555/how-to-inject-authenticationmanager-using-java-configuration-in-a-custom-filter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!