2010-09-08 6 views
17

Nous construisons une application Web disponible pour les utilisateurs authentifiés et anonymes. Si vous décidez de ne pas vous enregistrer/vous connecter, vous n'avez qu'un nombre limité de fonctionnalités. L'authentification de l'utilisateur est effectuée via OpenID avec Spring Security. Cela fonctionne bien. Cependant, l'application est également fournie avec une interface d'administration qui est déployée au <host>/<context-root>/admin. Pouvons-nous avoir deux domaines distincts avec Spring Security (par exemple, authentification de base pour /admin/**)? Comment cela doit-il être configuré?Deux domaines dans la même application avec Spring Security?

Répondre

18

Spring Security a ajouté la prise en charge de ce scénario dans la version 3.1, qui est actuellement disponible en tant que candidat à la publication. Il a été implémenté par SEC-1171 et les détails de la syntaxe sont dans le manuel inclus avec 3.1.

Cependant, il est assez simple à utiliser. Vous devez simplement définir plusieurs éléments http dans votre configuration Spring Security, un pour chaque domaine. Nous l'utilisons comme ceci:

<!-- Configure realm for system administration users --> 
<security:http pattern="/admin/**" create-session="stateless"> 
    <security:intercept-url pattern='/**' access='ROLE_ADMIN' requires-channel="https" /> 
    <security:http-basic/> 
</security:http> 


<!-- Configure realm for standard users --> 
<security:http auto-config="true" access-denied-page="/error/noaccess" use-expressions="true" create-session="ifRequired"> 
    <security:form-login login-page="/login" 
      ... 
      ... 
</security:http> 

L'essentiel à noter est le pattern="/admin/**" sur le premier élément http. Cela indique à Spring que toutes les URL sous /admin sont soumises à ce domaine au lieu du domaine par défaut - et donc les URL sous /admin utilisent l'authentification de base à la place.

+0

J'ai creusé partout en essayant de comprendre comment faire exactement cela, merci de l'indiquer si clairement! –

+1

Sécurité de printemps 3.1.0 a été officiellement publié le 7/12/2011 – lrkwz

+0

Je fais exactement cela et si je suis connecté à la section admin, je suis également connecté dans la section utilisateur, mais pas autorisé (bien sûr). Je pense que c'est parce que la sécurité du printemps détient l'autorisation en session sous une clé. Y at-il un moyen de configurer la sécurité de printemps au scénario où vous pouvez être connecté à la section admin et utilisateur en même temps avec une entité d'autorisation différente? –

0

Je ne peux pas penser à aller de l'avant droit d'avoir deux royaumes (et je ne l'ai pas essayé moi-même):

vous peut définir deux filtres in your web.xml où chacun de ces a une configuration de ressort différent et ergo un environnement propre. Les choses globales vont dans la config de l'application, le spécifique au domaine dans la configuration du filtre. Si c'est seulement pour une méthode d'authentification différente, vous pouvez write your own filter qui décide alors du filtre à appeler.

1

Solution possible:

  • Ajouter intercepteur URL pour /admin la demande "ROLE_ADMIN"
  • configuration de l'instance de org.springframework.security.web.authentication.www.BasicAuthenticationFilter pour intercepter l'URL /admin et authentifier l'utilisateur comme ROLE_ADMIN si elle fournit les informations d'identification appropriées

Exemple de configuration:

<security:intercept-url pattern="/admin" access="ROLE_ADMIN"/> 

<bean id="basicAuthenticationEntryPoint" 
     class="org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint"> 
    <property name="realmName" 
       value="WS realm"/> 
</bean> 

<bean id="basicAuthenticationProcessingFilter" 
     class="org.springframework.security.web.authentication.www.BasicAuthenticationFilter"> 
    <property name="authenticationManager" 
       ref="authenticationManager"/> 
    <property name="authenticationEntryPoint" 
       ref="basicAuthenticationEntryPoint"/>  
</bean> 

Remarque: l'implémentation par défaut de BasicAuthenticationFilter est un filtre passif, c'est-à-dire qu'il recherche simplement un en-tête auth basic dans la requête et s'il n'est pas présent - ne fait rien. Si vous voulez que le filtre à exiger explicitement l'authentification de base du client, vous devez étendre l'implémentation par défaut pour commencer à un point d'entrée d'authentification:

public class BasicAuthenticationFilter 
     extends org.springframework.security.web.authentication.www.BasicAuthenticationFilter { 

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { 

     final HttpServletRequest request = (HttpServletRequest) req; 
     final HttpServletResponse response = (HttpServletResponse) res; 

     String header = request.getHeader("Authorization"); 

     if ((header != null) && header.startsWith("Basic ")) { 
      super.doFilter(req, res, chain); 
     } else { 
      getAuthenticationEntryPoint().commence(request, response, new AuthenticationCredentialsNotFoundException("Missing credentials")); 
     } 
    } 
} 

De plus, vous devez modifier le filtre à appliquer à /admin URL uniquement - soit en codant en dur cette méthode dans doFilter ou en fournissant un bean wrapper approprié.