vendredi 6 juin 2014

Sécurisez votre application avec Spring Security 3.1

Spring Security, petit frère d'Acegi Security, est un framework qui fournit des mécanismes d'authentification et de sécurisation pour vos applications Java. Voici comment sécuriser votre application web en trois étapes...

Configuration dans le web.xml

Le fichier web.xml est le descripteur de déploiement de votre application web. Il est généralement situé dans le répertoire WEB-INF et définit les paramètres de base de votre application.

Commencez par définir un filtre de type FilterChainProxy dans le fichier web.xml.

<filter>
  <filter-name>My Spring Security Filter Chain Proxy</filter-name>
  <filter-class>org.springframework.security.web.FilterChainProxy</filter-class>
  <init-param>
    <param-name>targetBean</param-name>
    <param-value>springSecurityFilterChainProxy</param-value>
  </init-param>
</filter>

Puis définissez dessous les URLs concernées par ce filtre.

<filter-mapping>
  <filter-name>My Spring Security Filter Chain Proxy</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

Dans notre exemple, l'intégralité des URLs de l'application sont traitées par le filtre de Spring Security.

Configuration dans un fichier dédié

Une alternative consiste à créer un fichier de configuration dédié à la sécurité et à la référencer le dans votre web.xml.

<import resource="classpath:applicationContext-security.xml"/>

Collez-y le contenu suivant

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

<!-- dans la prochaine étape -->

</beans:beans>

Création des filtres de sécurité


Une chaîne de filtres ?

Le filtre définit dans le fichier de configuration est un bean de type FilterChainProxy.

Le FilterChainProxy définit une chaîne de filtre où chacun des filtres est appliqué en fonction du pattern de l'URL de la requête. Le paramétrage permet également de préciser l'ordre des filtres de sécurité de votre application.

A l'opposé, sous cousin le DelegatingFilterProxy appliquera l'intégralité des filtres sur l'ensemble des URLs.

Ci-dessous est présenté un bean de type FilterChainProxy avec trois paramétrages de filtres différents.

<beans:bean id="springSecurityFilterChainProxy" class="org.springframework.security.web.FilterChainProxy">
<beans:constructor-arg>
  <beans:list>
    <filter-chain pattern="/clog**" filters="httpSessionContextIntegrationFilter" />
    <filter-chain pattern="/log/**" filters="httpSessionContextIntegrationFilter" />
    <filter-chain pattern="/**" filters="httpSessionContextIntegrationFilter,exceptionTranslationFilter,filterSecurityInterceptor" />
  </beans:list>
</beans:constructor-arg>
</beans:bean>

Les URLs respectant le motif "/clog**" ou "/log/**" sont filtrées par un filtre unique nommé httpSessionContextIntegrationFilter.

Les autres URLs passeront dans trois filtres nommés respectivement httpSessionContextIntegrationFilter, exceptionTranslationFilter et filterSecurityInterceptor.


Quelques filtres intéressants...


1 - Le SecurityContextPersistenceFilter

Le filtre SecurityContextPersistenceFilter joue un double rôle.

Il est chargé de lier le contexte de sécurité (SecurityContext) à la session lors des requêtes HTTP. Le contexte de sécurité peut s'initialiser à l'aide du code Java suivant

SecurityContextHolder.getContext().setAuthentication(authManager)

authManager est un objet de type org.springframework.security.authentication.AuthenticationManager

Il est chargé de supprimer le contexte de sécurité de la session HTTP lorsque l'utilisateur se déconnecte.
Le contexte de sécurité peut être supprimé à l'aide du code Java suivant

SecurityContextHolder.clearContext();

Le filtre peut être créé sans paramètres comme ci-dessous.

<beans:bean id="httpSessionContextIntegrationFilter" class="org.springframework.security.web.context.SecurityContextPersistenceFilter"/>


2 - L'ExceptionTranslationFilter

Le filtre ExceptionTranslationFilter est chargé de réceptionner les exceptions levées par Spring Security. Ces exceptions seront généralement déclenchées par l'objet AbstractSecurityInterceptor qui est le fournisseur principal des services d'autorisation. Dès lors, si une requête est effectuée sur une URL non autorisée, une erreur d'autorisation sera levée puis récupérée par le filtre ExceptionTranslationFilter.

Dans un cas d'utilisation classique, il est possible de renseigner la propriété authenticationEntryPoint, ce qui aura pour effet de réorienter toutes les requêtes non autorisées vers une page de login.

Ci-dessous un exemple de configuration pour un ExceptionTranslationFilter

<beans:bean id="exceptionTranslationFilter" class="org.springframework.security.web.access.ExceptionTranslationFilter">
  <beans:property name="authenticationEntryPoint">
    <beans:bean class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
    <beans:property name="loginFormUrl" value="/start/index.jsp" />
  </beans:bean>
  </beans:property>
</beans:bean>


3 - Le FilterSecurityInterceptor

Le filtre FilterSecurityInterceptor est chargé de sécuriser les URLs par profil d'utilisateur. Pour configurer le filtre, il nous faut

1/ Créer un manager d'authentification
2/ Créer un manager d'accès
3/ Définir une liste de motifs d'URLs par profil d'utilisateur

Il peut être crée avec la configuration suivante :

<beans:bean id="filterSecurityInterceptor" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
<beans:property name="authenticationManager" ref="authenticationManager" />
  <beans:property name="accessDecisionManager" ref="accessDecisionManager" />
  <beans:property name="securityMetadataSource">
    <filter-security-metadata-source>
      <!-- Liste des règles -->
    </filter-security-metadata-source>
  </beans:property>
</beans:bean>

Un manager d'authentification peut être créé avec la configuration suivante.

<authentication-manager alias="authenticationManager">

<!-- Premier provider de credentials -->
<authentication-provider user-service-ref="dbAuthProvider" >
<password-encoder hash="md5" />
</authentication-provider>

<!-- Second provider de credentials -->
<authentication-provider ref="ldapAuthProvider">
<password-encoder hash="plaintext" />
</authentication-provider>
</authentication-manager>

On définit une liste de providers à appeler dans l'ordre dans lesquels ils sont définis. Dans cet exemple, une première authentification est effectuée sur une base de donnée avant d'interroger un annuaire LDAP en cas d'échec sur la base de données.

Un manager d'accès peut être créé avec la configuration suivante.

<beans:bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
  <beans:property name="allowIfAllAbstainDecisions"><beans:value>false</beans:value></beans:property>
  <beans:property name="decisionVoters">
  <beans:list>
    <beans:bean id="authVoter" class="org.springframework.security.access.vote.AuthenticatedVoter"></beans:bean>
    <beans:bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter">
    <beans:property name="rolePrefix">
      <beans:value></beans:value>
    </beans:property>
    </beans:bean>
  </beans:list>
</beans:property>
</beans:bean>

Enfin la liste des URLs est définie en utilisant des balises <intercept-url> à l'intérieur de la balise <filter-security-metadata-source> que nous avons vu précédemment.

<intercept-url pattern="/log/**" access="permitAll" />
<intercept-url pattern="/forbidden/**" access="denyAll" />
<intercept-url pattern="/pro/pro_110.do" access="hasAnyRole('superviseur','gestionnaire')" />
<intercept-url pattern="/pro/pro_110.jsp" access="hasRole('superviseur')" />

Aucun commentaire:

Enregistrer un commentaire

Un avis ? Une question ?
N'hésitez pas à laissez des commentaires !