【问题标题】:Spring Security 3: Problem autowiring UserDetailsManager/JdbcUserDetailsManagerSpring Security 3:自动装配 UserDetailsManager/JdbcUserDetailsManager 的问题
【发布时间】:2010-08-24 00:43:01
【问题描述】:

我正在研究 Peter Mularien 的 Spring Security 3,但在设置 UserDetailsManager 时遇到问题。

我按如下方式创建 JdbcUserDetailsManager bean:

<bean id="jdbcUserService" class="org.springframework.security.provisioning.JdbcUserDetailsManager">
    <property name="dataSource" ref="mySqlDb" />
    <property name="authenticationManager" ref="authenticationManager" />
</bean>

并像这样在我的控制器中自动装配其 UserDetailsManager 接口:

@Autowired
public UserDetailsManager userDetailsManager;

当我启动应用程序进行测试时,我得到以下异常:

Error creating bean with name 'changePasswordController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.security.provisioning.UserDetailsManager com.ebisent.web.ChangePasswordController.userDetailsManager; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [org.springframework.security.provisioning.UserDetailsManager] is defined: expected single matching bean but found 2: [org.springframework.security.provisioning.JdbcUserDetailsManager#0, jdbcUserService]

我搜索了我的项目,看看我是否可能在其他地方设置了 (Jdbc)UserDetailsManager,但我似乎没有这样做。如果我删除 bean 定义中的“id”属性,则歧义在 JdbcUserDetailsManager#0 和 JdbcUserDetailsManager#1 之间。

我的 web.xml 在两个地方引用了 app-config.xml:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>WEB-INF/spring/app-config.xml</param-value>
</context-param>

<servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>WEB-INF/spring/app-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

【问题讨论】:

  • 你是如何加载应用程序上下文的?
  • 我添加了一个编辑,显示我的 web.xml 文件中有两次 app-config.xml。这是我问题的根源吗?

标签: java security spring


【解决方案1】:

两次指定app-config.xml 肯定有问题,但这不是最初所述问题的答案。

Spring 似乎是根据类型自动装配的。 bean 是用类JdbcUserDetailsManager 定义的,它实现了UserDetailsManager

在我的控制器中,我正在自动装配接口UserDetailsManager。 Spring 两次找到接口,并抱怨它不知道该选择哪个。

添加@Qualifier 注释可以解决问题。这是它现在的样子:

@Autowired
@Qualifier("jdbcUserService")  // <-- this references the bean id
public UserDetailsManager userDetailsManager;

【讨论】:

    【解决方案2】:

    罗伯特, 是的。您的 web.xml 所说的是创建一个指向 app-config.xml 父级的 app-config.xml 的 Web 应用程序上下文。这意味着您有每个 bean 的两个副本 - 正如您所注意到的那样,这是不正确的。

    【讨论】:

      【解决方案3】:

      这似乎可以解决问题:

      1. 评论“jdbcUserService”
      2. 插入:

        <authentication-manager alias="authenticationManager">
                    <authentication-provider>
                    <jdbc-user-service data-source-ref="dataSource"/>
                    </authentication-provider> 
                    </authentication-manager>
        
      3. 创建数据源:

            <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost/secureApp"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
        </bean>
        
      4. 根据您使用的女巫数据源(在本例中为 MySQL)创建必要的配置。如果您使用的是 hibernate 或 jpa,请创建任何其他配置...

      5. 运行服务器。

      我今天能够重现这个。数据库已使用更改后的密码进行了更新。似乎身份验证管理器已经实例化了一个 JdbcUserDetailsManager ??

      【讨论】:

        猜你喜欢
        • 2011-01-24
        • 1970-01-01
        • 2018-05-08
        • 2011-12-29
        • 1970-01-01
        • 2020-07-12
        • 2014-04-09
        • 2016-03-29
        相关资源
        最近更新 更多