当前位置: 首页 > 知识库问答 >
问题:

如何将自定义DaoAuthenticationProvider加载到Spring上下文中?

别帅
2023-03-14

我对Spring Security有这个问题。

我有一个带有SecurityConfig类的java配置实现,它扩展了WebSecurityConfigureAdapter。

在这个类中,我想重写方法“configure()”

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

    //...

}   

一切正常,一切正常。

问题是Spring Context上没有加载“MyDaoAuthenticationProvider”组件。所以我无法注入或自动安装此类中的任何组件:

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
    }

}

这是AuthenticationHandler类:

@Component
public class AuthenticationHandler {

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

}

如果我将@Component放在MyDaoAuthenticationProvider类上,并在SecurityConfig类中添加@Autow的注释:

@Autowired
MyDaoAuthenticationProvider provider;

应用程序在开始时崩溃,错误如下:

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

我必须做些什么来解决这个问题?谢谢

编辑

解决方案

多亏了OrangeDog,我修复了此实现的问题:

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

使用此配置,bean被正确初始化,并且不再有错误“java.lang.IllegalArgumentException: A UserDetailsService必须设置”。

此外,bean被加载到Spring上下文中,因此DaoAuthenticationProvider中的所有注入组件都被正确解析

共有1个答案

谷梁波
2023-03-14

创建名为“myDaoAuthenticationProvider”[…]的bean时出错必须设置UserDetailsService

您的MyDaoAuthenticationProvider没有UserDetailsService。您必须实现、注入和/或设置一个。例如,在不使用@Component的情况下:

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

然后,您需要停止在configure方法中创建另一个。

如果您认为不需要,那么您可能不应该实现DaoAuthenticationProvider。也许您实际上想要实现一个通用的AuthenticationProvider,或者使用它的其他实现类。

 类似资料:
  • 问题内容: 我有一些带有自定义注释的类,不应实例化(抽象类,它只是真实bean的子组件)。但是在此类的顶部,在运行时,在上下文初始化阶段,我想将额外的bean放入应用程序上下文中。 因此,基本上,我需要扫描类路径,处理结果,并将新bean引入当前的应用程序上下文中。 似乎spring-mvc,spring-tasks和spring-integration正在这样做(我试图从源中学习它-没运气) 我

  • 我在spring boot应用程序中实现了firebase消息传递。为此,我创建了一个类似本文所述的bean,以便轻松访问实例。然后,该bean被注入到服务中。然后,当调用利用bean的服务方法时,所述服务被注入到我的控制器中。 现在我的问题是该项目的测试套件(使用JUnit5 根本原因: 注意:这些错误只有在整体运行testsuite时才会出现。如果我自己运行一个测试类,则不会出现错误。 解决这

  • 我有一些不应该实例化的带有自定义注释的类(抽象类,它只是实际bean的子组件)。但是在这些类之上,在运行时,在上下文初始化阶段,我想在应用程序上下文中添加额外的bean。 因此,基本上我需要扫描类路径,处理结果,并将新bean引入curent应用程序上下文。 似乎是spring-mvc、spring-tasks和spring-integration在做这件事(我试着从源代码中学习--没有运气) 我

  • 我有需要测试的REST服务。该服务具有Spring Security身份验证,我需要在测试或模拟中关闭它。我决定嘲笑它,因为我不能关掉它。我为此编写了,但现在未加载上下文: 在我的主要源代码中,我有一些config类加载了一些其他bean,而it类在我的测试中没有加载,我有一个例外: 我做错了什么?有人能帮我吗?我使用了,但在该版本中,无法工作,因为属性不再存在。

  • 我有一个基于令牌的用户身份验证的Jersey REST应用程序。当请求传入时,会创建一个自定义的对象,并将其作为一个属性添加到 的用法,我想知道是否可以使用injection将这个< code>RestContext注入到我的资源和其他过滤器中(例如,我有一个过滤器,它从< code>RestContext中创建一个< code>SecurityContext),但是我找不到答案。一般来说,我如何

  • 问题内容: 如何添加自定义CSS文件?以下配置对我不起作用: 结果: 问题答案: 一种简单的方法是将其添加到您的: 然后将文件放入文件夹。