2010-09-08 4 views
17

Wir erstellen eine Webanwendung, die sowohl für authentifizierte als auch für anonyme Benutzer verfügbar ist. Wenn Sie sich nicht registrieren/anmelden, haben Sie nur eine begrenzte Anzahl von Funktionen. Die Benutzerauthentifizierung erfolgt über OpenID mit Spring Security. Das funktioniert gut.Zwei Realms in gleicher Anwendung mit Spring Security?

Die Anwendung enthält jedoch auch eine Admin-Benutzeroberfläche, die unter <host>/<context-root>/admin bereitgestellt wird. Können wir zwei separate Realms mit Spring Security haben (z. B. Basic Auth für /admin/**)? Wie muss das konfiguriert werden?

Antwort

18

Spring Security hat Unterstützung für dieses Szenario in Version 3.1 hinzugefügt, das derzeit als Release Candidate verfügbar ist. Es wurde von SEC-1171 implementiert und Details der Syntax sind im Handbuch 3.1 enthalten.

Es ist jedoch ziemlich einfach zu bedienen. Im Grunde definieren Sie einfach mehrere http Elemente in Ihrer Spring Security-Konfiguration, eine für jedes Realm. Wir verwenden es wie folgt aus:

<!-- 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> 

Der Schlüssel, was zu beachten die pattern="/admin/**" am ersten http Element ist. Dadurch wird Spring mitgeteilt, dass alle URLs unter /admin diesem Bereich anstelle des Standardbereichs unterliegen. Daher verwenden URLs unter /admin stattdessen die Standardauthentifizierung.

+0

Ich habe graben überall versucht, herauszufinden, wie genau das zu tun, danke für das Aufzeigen so klar! –

+1

Federsicherung 3.1.0 wurde offiziell am 7.12.2011 freigegeben – lrkwz

+0

Ich mache genau das und wenn ich im Admin-Bereich angemeldet bin, bin ich auch im Benutzerbereich angemeldet, aber nicht autorisiert (natürlich). Ich denke, das liegt daran, dass die Frühjahrssicherheit die Genehmigung in der Sitzung unter einem Schlüssel hält. Gibt es eine Möglichkeit, Spring Security auf ein Szenario zu konfigurieren, bei dem Sie gleichzeitig mit verschiedenen Autorisierungsinstanzen im Admin- und im Benutzerbereich angemeldet sein können? –

0

ich nicht von einem geraden Weg nach vorn denken kann zwei Bereiche haben (und ich es nicht selbst versuchte):

Sie zwei Filter definieren können in your web.xml, wo jeder von denen eine andere Federkonfiguration hat und ergo eine eigene Umgebung. Die globalen Dinge gehen in die App Config, die Realm-Specific in der Filter Config.

Wenn es nur für eine andere Authentifizierungsmethode ist, können Sie write your own filter entscheiden, welcher Filter dann aufgerufen wird.

1

Mögliche Lösung:

  • für /admin URL Interceptor In der erfordert "ROLE_ADMIN"
  • konfigurieren Instanz org.springframework.security.web.authentication.www.BasicAuthenticationFilter die /admin URL abzufangen und Benutzer als ROLE_ADMIN authentifizieren, wenn sie die entsprechenden Anmeldeinformationen bietet

Beispielkonfiguration:

<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> 

Hinweis: Die Standardimplementierung von BasicAuthenticationFilter ist ein passiver Filter, d. H. Es sucht nur nach einem Basis-Auth-Header in der Anfrage und wenn es nicht vorhanden ist - tut nichts. Wenn Sie die Filter wollen die Basis-Authentifizierung vom Client explizit benötigen, müssen Sie die Standardimplementierung erweitern beginnen Eintrittspunkt zur Authentifizierung:

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")); 
     } 
    } 
} 

Darüber hinaus müssen Sie den Filter optimieren, um /admin URL anwenden Nur - entweder durch Festcodierung in doFilter Methode oder durch Bereitstellung einer entsprechenden Wrapper Bean.