2012-05-29 2 views
1

Essayer de faire des expériences avec Spring MVC et Spring Security:@Service instancié deux fois

@Controller 
@RequestMapping("/auth") 
public class AuthController { 
    @Autowired 
    // @Qualifier("userDetailsService") - tried adding this 
    private MyUserDetailsService userDetailsService; 
    ... 
} 

// @Scope("singleton") - tried adding this 
@Service("userDetailsService") 
public class MyUserDetailsService implements UserDetailsService { 
    ... 
} 

context.xml complète que j'ai:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:mvc="http://www.springframework.org/schema/mvc" 
    xmlns:security="http://www.springframework.org/schema/security" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
     http://www.springframework.org/schema/context 
     http://www.springframework.org/schema/context/spring-context-3.0.xsd 
     http://www.springframework.org/schema/mvc 
     http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd 
     http://www.springframework.org/schema/security 
     http://www.springframework.org/schema/security/spring-security-3.0.xsd"> 

    <!-- ORIGINAL springmvc-servlet.xml --> 
    <mvc:annotation-driven /> 
    <mvc:resources mapping="/static/**" location="/static/" /> 

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
     <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> 
     <property name="prefix" value="/WEB-INF/jsp/"></property> 
     <property name="suffix" value=".jsp"></property> 
    </bean> 

    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" /> 
    <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" /> 

    <context:annotation-config /> 
    <context:component-scan base-package="com.xxxxxxxxx" /> 
    <!-- end ORIGINAL springmvc-servlet.xml --> 

    <!-- FROM springmvc-security.xml --> 
    <security:global-method-security secured-annotations="enabled"> 
    </security:global-method-security> 

    <security:http auto-config="true" access-denied-page="/auth/denied"> 
     <security:intercept-url pattern="/admin/*" access="ROLE_ADMIN"/>   
     <security:intercept-url pattern="/user/*" access="ROLE_USER"/> 
     <security:intercept-url pattern="/auth/login" access="IS_AUTHENTICATED_ANONYMOUSLY"/> 
     <security:intercept-url pattern="/auth/register" access="IS_AUTHENTICATED_ANONYMOUSLY"/> 
     <security:intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/> 
     <security:form-login login-page="/auth/login" authentication-failure-url="/auth/login?login_error=true" default-target-url="/user"/> 
     <security:logout logout-url="/auth/logout" logout-success-url="/" invalidate-session="true"/> 
     <security:openid-login authentication-failure-url="/login?login_error=t" user-service-ref="openIdUserDetailsService" /> 
    </security:http> 

    <security:authentication-manager> 
     <security:authentication-provider user-service-ref="userDetailsService" /> 
    </security:authentication-manager> 
    <!-- end FROM springmvc-security.xml -->  
</beans> 

Pour une raison quelconque, il y a 2 cas de MyUserDetailsService créé. Le premier est utilisé par Spring Security et le second est injecté au AuthController. Quelle est la bonne approche dans le cas où je veux avoir une seule instance de MyUserDetailsService?

+0

Intéressant, je me demandais toujours comment faire fonctionner la sécurité de printemps dans un contexte d'application avec d'autres haricots - je suppose qu'ils courent dans les séparés. –

+0

Btw dans ma configuration actuelle UserDetailsService est déclaré uniquement dans SecurityContext et non dans ApplicationContext (autoscan est désactivé). –

Répondre

1

Vous n'avez pas montré assez de configuration pour être certain, mais je parierais de l'argent que vous êtes confus sur la façon dont Spring ApplicationContexts devrait être géré dans une application Spring MVC. Ma réponse à une autre question sur le même problème est presque certainement ce que vous devez lire:

Declaring Spring Bean in Parent Context vs Child Context

Vous avez très probablement déclaré votre grain de service (soit explicitement ou avec un balayage des composants) à la fois la racine et les contextes enfants de votre application. Étant un bean service, il ne devrait vivre que dans le contexte racine. Vous pouvez également profiter de la lecture de cette réponse:

Spring XML file configuration hierarchy help/explanation

+0

J'ai mis à jour la question avec ma configuration contextuelle complète. Pourriez-vous s'il vous plaît vérifier? – agibalov

+0

C'est le fichier de contexte qui appartient à votre DispatcherServlet. Vous devriez en avoir un dans votre fichier web.xml nommé "springmvc". Montre également comment votre contexte racine est initialisé. C'est probablement aussi fait dans votre web.xml, par un ContextLoaderListener, et avec un paramètre contextConfigLocation. –

+0

Cela m'a pris environ une heure, mais maintenant je comprends. Merci pour votre réponse :-) – agibalov

0

cette configuration fonctionne pour moi:

<security:authentication-manager> 
<security:authentication-provider user-service-ref="userService"> 

et

<bean id="userService" class="com.mydomain.service.UserDetailsServiceImpl" /> 

A tutorial here.

+0

Cela ne va pas empêcher deux d'être créés. Il va simplement changer le nom d'un ou des deux beans créés. –

+0

@NimChimpsky: renommé en 'theUserDetailsService', c'est toujours pareil. – agibalov

+0

@ loki2302 oh vous l'avez changé dans l'application cotnext aussi? Est-ce que vous implémentez userdetailsservice ailleurs alors? – NimChimpsky