2016-04-21 6 views
1

Ich habe dieses Problem mit Spring Security.Wie Laden eines benutzerdefinierten DaoAuthenticationProvider in den Spring-Kontext?

Ich habe eine Java-Config-Implementierung mit einer SecurityConfig-Klasse, die WebSecurityConfigurerAdapter erweitert.

In dieser Klasse ich die Methode "configure()" außer Kraft setzen will

@Configuration 
@EnableWebSecurity 
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, proxyTargetClass = true) 
public class SecurityConfig extends WebSecurityConfigurerAdapter{ 

    @Override 
    protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
     MyDaoAuthenticationProvider provider = new MyDaoAuthenticationProvider(); 
     provider.setPasswordEncoder(passwordEncoder()); 
     provider.setUserDetailsService(securityService); 
     auth.authenticationProvider(provider); 
    } 

    //... 

} 

Alles ist in Ordnung und es funktioniert.

Das Problem ist, dass "MyDaoAuthenticationProvider" -Komponente nicht im Spring Context geladen ist. So kann ich keine Komponenten in dieser Klasse injizieren oder Autowired:

public class MyDaoAuthenticationProvider extends DaoAuthenticationProvider { 

    @Autowired 
    AuthenticationHandler authenticationHandler; // <- authenticationHandler is null, is not resolved 

    @Override 
    public Authentication authenticate(Authentication authentication) throws AuthenticationException { 
     authenticationHandler.authenticate(authentication); // <- NullPointerException in this point 
    } 

} 

Dies ist die AuthenticationHandler Klasse:

@Component 
public class AuthenticationHandler { 

    public void authenticate (Authentication authentication) { 
     // do stuff 
    } 

} 

Wenn ich die @Component auf der MyDaoAuthenticationProvider Klasse setzen und ich hinzufügen @ Autowired Anmerkung im SecurityConfig Klasse:

@Autowired 
MyDaoAuthenticationProvider provider; 

der Absturz der Anwendung auf den Start mit diesem Fehler:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myDaoAuthenticationProvider' defined in file [...\MyDaoAuthenticationProvider.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: A UserDetailsService must be set 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1578) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772) 
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839) 
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538) 
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:446) 
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:328) 
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107) 
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4812) 
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5255) 
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) 
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408) 
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    at java.lang.Thread.run(Thread.java:745) 
Caused by: java.lang.IllegalArgumentException: A UserDetailsService must be set 
    at org.springframework.util.Assert.notNull(Assert.java:115) 
    at org.springframework.security.authentication.dao.DaoAuthenticationProvider.doAfterPropertiesSet(DaoAuthenticationProvider.java:105) 
    at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.afterPropertiesSet(AbstractUserDetailsAuthenticationProvider.java:122) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574) 
    ... 21 more 

Was muss ich tun, um dieses Problem zu lösen? Danke.

EDIT

SOLUTION

Dank OrangeDog, ich das Problem bei dieser Implementierung behoben:

@Bean 
public MyDaoAuthenticationProvider myAuthProvider() throws Exception { 
    MyDaoAuthenticationProvider provider = new MyDaoAuthenticationProvider(); 
    provider.setPasswordEncoder(passwordEncoder()); 
    provider.setUserDetailsService(securityService); 
    return provider; 
} 

@Override 
protected void configure(AuthenticationManagerBuilder auth) throws Exception { 
    auth.authenticationProvider(myAuthProvider()); 
} 

Mit dieser Konfiguration wird die Bohne richtig initialisiert und es gibt nicht mehr die Fehler "java.lang.IllegalArgumentException: Ein UserDetailsService muss festgelegt werden".

Außerdem wird die Bean in den Spring-Kontext geladen, sodass alle im DaoAuthenticationProvider eingefügten Komponenten korrekt aufgelöst werden.

Antwort

2

Error creating bean with name 'myDaoAuthenticationProvider' [...] A UserDetailsService must be set

Ihr MyDaoAuthenticationProvider hat kein UserDetailsService. Sie müssen eines implementieren, injizieren und/oder setzen.

Wenn Sie nicht glauben, dass Sie eine benötigen, sollten Sie wahrscheinlich keine DaoAuthenticationProvider implementieren. Vielleicht möchten Sie tatsächlich ein generisches AuthenticationProvider implementieren oder seine anderen implementierenden Klassen verwenden.

Zum Beispiel ohne @Component mit:

@Bean 
public MyDaoAuthenticationProvider myAuthProvider() { 
    MyDaoAuthenticationProvider provider = new MyDaoAuthenticationProvider(); 
    provider.setPasswordEncoder(passwordEncoder()); 
    provider.setUserDetailsService(securityService); 
    return provider; 
} 

Sie müssen dann ein anderes in Ihrem configure Verfahren zu schaffen stoppen.

+0

Nein, ich habe es! Ich habe ihn mit diesem festgelegt: provider.setUserDetailsService (securityService); –

+0

Es scheint jedoch, dass Spring keine Bean erstellen kann, wenn die "configure" -Methode noch nicht ausgeführt wird. –

+0

Sie haben es in dem Code, der funktioniert, wenn Sie 'new MyDaoAuthenticationProvider()' aufrufen. Wenn Sie möchten, dass es eine '@ Component'-Bean ist, müssen Sie es anders machen. – OrangeDog

Verwandte Themen