2014-02-07 5 views
54

Ich verwende Spring Security 3.2 und Spring 4.0.1Wie einzuspritzen AuthenticationManager mit Hilfe von Java-Konfiguration in einem benutzerdefinierten Filter

Ich arbeite einen XML-Config in eine Java-Config auf konvertieren. Als ich AuthenticationManager mit @Autowired in meinem Filter mit Anmerkungen versehen, erhalte ich eine Ausnahme

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: {} 

Ich habe versucht, AuthenticationManagerFactoryBean Injektion, aber das nicht auch mit einer ähnlichen Ausnahme. Hier

ist die XML-Konfiguration Ich arbeite von

<?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> 

Hier ist die Java-Konfiguration ist, ich bin versucht,

@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 
    } 
} 

Und das ist die kundenspezifische Filterklasse. Die Linie mir Mühe geben, ist der Setter für 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); 
    } 
} 
+0

Darf ich fragen, Was macht der Autowired direkt über einem Override? Ich habe das noch nie zuvor gesehen. Was ist damit verkabelt? – Stephane

+0

Wie haben Sie Ihren benutzerdefinierten Filter hinzugefügt? Ich habe meinen eigenen Filter und Authentifizierungsanbieter erstellt. Aber ich weiß nicht, wie man sie konfiguriert, um zusammen zu arbeiten. Hier ist meine Frage http://stackoverflow.com/questions/30502589/spring-boot-hmac-authentication-how-to-add-custom-authenticationprovider-and-a – Loco

Antwort

91

Aufschalten Methode authenticationManagerBean in WebSecurityConfigurerAdapter die AuthenticationManager zu belichten gebaut configure(AuthenticationManagerBuilder) als Spring-Bean mit:

Zum Beispiel:

@Bean(name = BeanIds.AUTHENTICATION_MANAGER) 
    @Override 
    public AuthenticationManager authenticationManagerBean() throws Exception { 
     return super.authenticationManagerBean(); 
    } 
+0

@qxixp ", um den AuthenticationManager verfügbar zu machen, der mit configure (AuthenticationManagerBuilder) als eine Frühlingsbohne " – Roger

+1

@Roger, warum müssen wir den AuthenticationManager manuell aussetzen? – qxixp

+7

@qxixp Sie können nur eine federverwaltete Bean automatisch in den Autowire laden. Wenn es nicht als Bean angezeigt wird, können Sie es nicht automatisch starten. – Roger