2010-09-08 16 views
17

Stiamo creando un'applicazione Web disponibile per gli utenti autenticati e anonimi. Se decidi di non registrare/accedere hai solo un set limitato di funzionalità. L'autenticazione dell'utente viene eseguita su OpenID con Spring Security. Funziona beneDue reami nella stessa applicazione con Spring Security?

Tuttavia, l'applicazione viene fornita con un'interfaccia utente di amministrazione che viene distribuita su <host>/<context-root>/admin. Possiamo avere due domini separati con Spring Security (ad es. Autenticazione di base per /admin/**)? Come deve essere configurato?

risposta

18

Spring Security ha aggiunto il supporto per questo scenario nella versione 3.1, che è attualmente disponibile come Release Candidate. È stato implementato da SEC-1171 e i dettagli della sintassi sono nel manuale incluso in 3.1.

Tuttavia è piuttosto semplice da usare. Fondamentalmente, si definiscono più elementi http nella configurazione di Spring Security, uno per ciascun dominio. Noi stiamo usando in questo modo:

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

La cosa fondamentale da notare è la pattern="/admin/**" sul primo elemento http. Ciò indica a Spring che tutti gli URL sotto /admin sono soggetti a tale dominio anziché all'area di autenticazione predefinita, pertanto gli URL sotto /admin utilizzano invece l'autenticazione di base.

+0

Sto scavando dappertutto cercando di capire come fare esattamente questo, grazie per averlo indicato con tanta chiarezza! –

+1

Sicurezza di primavera 3.1.0 è stato ufficialmente rilasciato il 7/12/2011 – lrkwz

+0

Sto facendo esattamente questo e se sono loggato nella sezione admin sono anche loggato nella sezione utente ma non autorizzato (ovviamente). Penso che questo sia dovuto al fatto che la sicurezza di primavera detiene l'autorizzazione in sessione sotto una chiave. Esiste un modo per configurare la sicurezza di primavera in uno scenario in cui è possibile accedere agli amministratori e alla sezione utente contemporaneamente con entità di autorizzazione diversa? –

0

non riesco a pensare a un modo dritto in avanti per avere due regni (e non ho provato io stesso):

si possono definire due filtri in your web.xml in cui ciascuno di questi presenta una configurazione a molla diversa e ergo un proprio ambiente. Le cose globali vanno nella configurazione dell'app, il regno specifico nella configurazione del filtro.

se è solo per un metodo di autenticazione diverso, è possibile write your own filter che decide il filtro da chiamare.

1

Possibile soluzione:

  • Aggiungi intercettore URL /admin la richiede "ROLE_ADMIN"
  • Configura istanza di org.springframework.security.web.authentication.www.BasicAuthenticationFilter per intercettare l'URL /admin e autenticare l'utente come ROLE_ADMIN se fornisce le credenziali appropriate

Esempio di configurazione:

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

Nota: l'implementazione predefinita di BasicAuthenticationFilter è un filtro passivo, ovvero cerca semplicemente un'intestazione di autenticazione di base nella richiesta e, se non è presente, non fa nulla. Se si desidera che il filtro per richiedere esplicitamente l'autenticazione di base da parte del cliente, è necessario estendere l'implementazione predefinita per iniziare a autenticazione del punto di entrata:

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

Inoltre, è necessario modificare il filtro da applicare ai /admin URL solo - codificandolo nel metodo doFilter o fornendo un bean wrapper appropriato.

Problemi correlati