2010-08-24 7 views
2

Je travaille sur Spring Security 3 de Peter Mularien et je rencontre un problème lors de la configuration de UserDetailsManager.Spring Security 3: Problème autowiring UserDetailsManager/JdbcUserDetailsManager

je crée le haricot JdbcUserDetailsManager comme suit:

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

et lier automatiquement son interface UserDetailsManager dans mon contrôleur comme ceci:

@Autowired 
public UserDetailsManager userDetailsManager; 

Lorsque je démarre l'application pour le tester, je reçois l'exception suivante:

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] 

J'ai cherché à travers mon projet pour voir si J'ai peut-être installé (Jdbc) UserDetailsManager ailleurs, mais je ne semble pas l'avoir fait. Si je supprime l'attribut "id" dans la définition du bean, alors l'ambiguïté est entre JdbcUserDetailsManager # 0 et JdbcUserDetailsManager # 1.

Mes références web.xml app-config.xml en deux endroits:

<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

Comment chargez-vous le contexte de l'application? –

+0

J'ai ajouté une modification montrant que j'ai app-config.xml deux fois dans mon fichier web.xml. Est-ce la source de mon problème? – outis

Répondre

3

Il y avait certainement un problème avec la spécification de app-config.xml deux fois, mais ce n'est pas la réponse au problème initialement indiqué.

Il semble que Spring autowires basé sur le type. Le bean est défini avec la classe JdbcUserDetailsManager, qui implémente UserDetailsManager. Dans mon contrôleur, je suis autowiring l'interface UserDetailsManager. Spring trouve deux fois l'interface et se plaint de ne pas savoir laquelle choisir. L'ajout de l'annotation @Qualifier résout le problème.

Voici à quoi il ressemble maintenant:

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

Robert, Oui. Ce que dit votre fichier web.xml est de créer un contexte d'application web de app-config.xml pointant vers un parent de app-config.xml. Cela signifie que vous avez deux copies de chaque grain - ce qui, comme vous l'avez remarqué, est incorrect.

0

cela semble faire l'affaire:

  1. Commentaire du "jdbcUserService"
  2. Insérer:

    <authentication-manager alias="authenticationManager"> 
          <authentication-provider> 
          <jdbc-user-service data-source-ref="dataSource"/> 
          </authentication-provider> 
          </authentication-manager> 
    
  3. Créer une source de données:

    <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. Créez la configuration nessecary en fonction de la source de données que vous utilisez (MySQL dans ce cas). Créez toute configuration supplémentaire si vous utilisez hibernate ou jpa ...

  5. Exécutez le serveur.

J'ai été capable de reproduire cela aujourd'hui. La base de données a été mise à jour avec le mot de passe modifié. Il semble que le gestionnaire d'authentification instancie déjà un JdbcUserDetailsManager ??

Questions connexes