我正在使用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>
答案 0 :(得分:3)
指定app-config.xml
两次肯定存在问题,但这不是最初陈述的问题的答案。
看来Spring基于类型自动装配。 bean使用类JdbcUserDetailsManager
定义,该类实现UserDetailsManager
。
在我的控制器中,我正在自动连接接口UserDetailsManager
。 Spring发现界面两次,并抱怨它不知道要选哪个。
添加@Qualifier
注释可以解决问题。以下是它现在的样子:
@Autowired
@Qualifier("jdbcUserService") // <-- this references the bean id
public UserDetailsManager userDetailsManager;
答案 1 :(得分:2)
罗伯特, 是。您的web.xml所说的是创建指向app-config.xml父级的app-config.xml的Web应用程序上下文。这意味着你有两个每个bean的副本 - 正如你所注意到的那样是不正确的。
答案 2 :(得分:0)
这似乎可以解决问题:
插入:
<authentication-manager alias="authenticationManager">
<authentication-provider>
<jdbc-user-service data-source-ref="dataSource"/>
</authentication-provider>
</authentication-manager>
创建数据源:
<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>
根据您使用的数据源创建nessecary配置(在本例中为MySQL)。如果您使用的是hibernate或jpa,请创建任何其他配置...
运行服务器。
我今天能够重现这一点。使用更改的密码更新数据库。似乎身份验证管理器已经实例化了一个JdbcUserDetailsManager ??