Introduzione

Gestire gli aspetti di security di una applicazione significa garantire che il sistema sia in grado di valutare le informazioni di accesso fornite dall'utente, e in base ad esse, permettere o no l'ingresso. Inoltre deve essere in grado di discernere da queste stesse informazioni le abilitazioni dell'utente all'accesso delle varie risorse del sistema. Le problematiche di sicurezza posseggono degli aspetti standard che nella loro generalità costituiscono una struttura in qualche modo "esterna" all'applicazione. È un sicuro vantaggio utilizzare un framework che in qualche modo codifichi questi standard e li gestisca in maniera appropriata, evitando di dover reinventare soluzioni a problemi già studiati e risolti positivamente dalla comunità degli sviluppatori.

Acegi Security System è un framework che utilizza le caratteristiche di Injection of Control di Spring e fornisce un insieme di beanche risolvono tutte le problematiche più comuni, compreso l'interfacciamento verso un sistema di Single Sign On come CAS. Questo articolo fornisce una breve panoramica del framework Acegi: nel prossimo paragrafo si espone la struttura generale passando successivamente un po' più nel dettaglio dei principali componenti.

Struttura generale

La figura 1 mostra la struttura generale di Acegi Security System:

Figura 1 - Schema generale del sistema Acegi
Figura 1 - Schema generale del sistema Acegi

Acegi si basa su un insieme di filtri Servlet per implementare la messa in sicurezza di un'applicazione web. I filtri sono uno standard della tecnologia servlet e permettono di inserirsi nel ciclo di vita della richiesta web. I filtri di Acegi delegano a specifici componenti l'implementazione dei diversi aspetti della security. Tra tali componenti quelli principali sono i security interceptors che si affidano agli altri due componenti mostrati in figura: gli authentication managers e gli access decision managers. Il primo gestisce la fase di autenticazione che è quella preliminare che precede l'accesso effettivo all'applicazione. Il sistema deve essere in grado di verificare l'identità dell'utente che cerca di effettuare il login al sistema e lo fa tramite le sue credenziali di accesso, normalmente la password. Superata questa prima fase deve verificare, attraverso le informazioni a corredo delle credenziali sopra riportate, a quali risorse l'utente è abilitato ad accedere, e qui entrano in gioco gli access decision managers.

Autenticazione

L'interfaccia seguente è l'astrazione principale che identifica il processo di autenticazione:

public interface AuthenticationManager {
  public Authentication authenticate(Authentication authentication)
    throws AuthenticationException;
}
public interface AccessDecisionManager {
  public void decide(Authentication authentication, Object object, ConfigAttributeDefinition config)
    throws AccessDeniedException;

  public boolean supports(ConfigAttribute attribute);

  public boolean supports(Class clazz);
}
<bean id="accessDecisionManager" class="net.sf.acegisecurity.vote.UnanimousBased">
  <property name="decisionVoters">
    <list>
      <ref bean="roleVoter"/>
    </list>
  </property>
</bean>
public interface AccessDecisionVoter {
  public static final int ACCESS_GRANTED = 1;
  public static final int ACCESS_ABSTAIN = 0;
  public static final int ACCESS_DENIED = -1;

  public boolean supports(ConfigAttribute attribute);

  public boolean supports(Class clazz);

  public int vote(Authentication authentication, Object object, ConfigAttributeDefinition config);
}
<filter>
  <filter-name>myFilter</filter-name>
  <filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
  <init-param>
    <param-name>targetClass</param-name>
    <param-value>myFilterBean</param-value>
  </init-param>
</filter>
<bean id="securityEnforcementFilter" class="net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter">
  <property name="securityInterceptor">
    <ref bean="securityInterceptor"/>
  </property>
  <property name="authenticationEntryPoint">
    <ref bean="authenticationEntryPoint"/>
  </property>
</bean>
<bean id="securityInterceptor" class="net.sf.acegisecurity.intercept.web.FilterSecurityInterceptor">
  <property name="authenticationManager">
    <ref bean="authenticationManager"/>
  </property>
  <property name="accessDecisionManager">
    <ref bean="accessDecisionManager"/>
  </property>
  <property name="objectDefinitionSource">
    <value>
      CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
      \A/admin/.*\Z=ROLE_ADMIN
      \A/oper/.*\Z=ROLE_OPER
    </value>
  </property>
</bean>