vendredi 23 janvier 2015

A graceful Golang install on Jenkins



1 - Go to Jenkins administration and install the last version of Custom Tools Plugin


2 - Then, go to Configure System and click on Custom tool installations button and Add Installer


3 - Fill it with the following configuration (you can use the latest go version)


4 - Use go as label and /$HOME/tools/go/1.3.3 as Tool Home


5 - Copy/paste the following script in command area

#!/bin/sh

set -e

GO_VERSION=1.3.3
GO_DIR=${HOME}/tools/go/${GO_VERSION}
GO_TARGZ=go${GO_VERSION}.linux-amd64.tar.gz

mkdir -p "${GO_DIR}"

# we'll use go too...
export PATH=${GO_DIR}/bin:${PATH}
export GOROOT=${GO_DIR}


#################################################
# Check & install Golang
#################################################

if [ -x "${GO_DIR}"/bin/go ] ; then

    echo "Go ${GO_VERSION} already installed"

else

    # cleanup incomplete installation
    [ -e "${GO_TARGZ}" ] && rm -f "${GO_TARGZ}"
    [ -e "${GO_DIR}" ] && rm -rf "${GO_DIR}"

    # wget the binary archive
    wget https://storage.googleapis.com/golang/${GO_TARGZ}

    # untar in $GO_DIR
    mkdir -p "${GO_DIR}"
    tar -xvz -C "${GO_DIR}" --strip-components=1 -f "${GO_TARGZ}"

fi

6 - Go to your project configuration, tick Install custom tools checkbox in Build Environment and select your installed tool as followed.


Then all you have to do is use your go commands with an Execute Shell!


mercredi 23 juillet 2014

Un pattern observer en Java


Dans la série des patterns que l'on retrouve souvent dans le monde du développement, le pattern observer est très fréquemment utilisé. En java, ce pattern peut être mis en place très simplement avec l'aide des classes de java.util du JDK : java.util.Observablejava.util.Observer

java.util.Observable : représente le sujet, c'est à dire l'objet qui doit être observé

java.util.Observer : représente une entité qui doit se tenir informée de l'évolution du sujet


Pour mettre en place ce pattern, mettons en place un objet observable, notre sujet. Cet objet qui hérite de java.util.Observable détient une information utile qui intéressera nos observateurs, la température.
package org.benc.observer.javautil;

public class Sujet extends java.util.Observable {

int temperature;

public int getTemperature() {
     return temperature;
  }

public void setTemperature(int temperature) {
    this.temperature = temperature;
    setChanged(); // J'informe que mon état a changé
  }
}

Puis implémentons notre objet qui observe, héritant de ll'interface java.util.Observer
package org.benc.observer.javautil;

public class Observer implements java.util.Observer {

String nom;

public Observer(java.util.Observable o, String nom) {
    this.nom = nom;
    o.addObserver(this); // A l'instanciation, je m'enregistre auprès du sujet que je souhaite suivre
  }

public void update(java.util.Observable o, Object arg) {
  if(o instanceof Sujet) {
    Sujet sujet = (Sujet) o;
    System.out.println("Moi, "+nom+", je suis informé de la nouvelle valeur de mon sujet : "+valeurAffichage);
  }
  // Si je m'intéresse à d'autres types de sujet, je traite les autres cas
  // if(o instanceof Sujet2) ...
 }
}

Et c'est tout !

On peut alors tester nos deux classes avec le bout de code suivant.
package org.benc.observer.javautil;

public class Main {

public static void main(String[] args) {
  Sujet monUniqueSujet = new Sujet();

  new Observer((Sujet) monUniqueSujet, "R1D1");
  new Observer((Sujet) monUniqueSujet, "R2D2");

  monUniqueSujet.setTemperature(18);
  monUniqueSujet.notifyObservers();

  monUniqueSujet.setTemperature(180); 
  monUniqueSujet.notifyObservers();
 }
}

Ce qui affichera :
Moi, R2D2, je suis informé de la nouvelle valeur de mon sujet : 18
Moi, R1D1, je suis informé de la nouvelle valeur de mon sujet : 18
Moi, R2D2, je suis informé de la nouvelle valeur de mon sujet : 180
Moi, R1D1, je suis informé de la nouvelle valeur de mon sujet : 180

jeudi 17 juillet 2014

Sécurisez votre application avec Spring Security


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 les trois étapes pour sécuriser votre appli web.

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.

Commençons 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.

Création d'un fichier de configuration séparé

Créez un fichier de configuration applicationContext-security.xml puis référencez le dans votre web.xml.

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

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

   <!-- Ici les filtres, dans la prochaine étape... -->

</beans:beans>

Création des filtres de sécurité


Paramétrage de la chaîne de filtres

Le filtre définie dans votre fichier de configuration est un bean de type FilterChainProxy
Ce type définit une chaîne de filtre paramétrable par URL, ce qui permet une gestion des filtres et des droits relativement fine. On précise la liste et l'ordre des filtres Spring Security appliqués par pattern d'URLs.

A l'opposé, la chaîne 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 patterne "/clog**" ou "/log/**" sont filtrées par un filtre unique définit dans le bean portant le nom httpSessionContextIntegrationFilter.

Les autres URLs sont filtrées par trois filtres définis dans les beans portant les noms httpSessionContextIntegrationFilter, exceptionTranslationFilter et filterSecurityInterceptor.


Les filtres les plus utilisés


1 - Le filtre 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 également chargé de supprimer le contexte de sécurité de la session HTTP lorqu'un utilisateur se déconnecte. Le contexte de sécurité peut être supprimé à l'aide du code Java suivant

SecurityContextHolder.clearContext();

En configuration de base, le filtre peut être créé sans paramètres comme ci-dessous.

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


2 - Le filtre ExceptionTranslationFilter

Le filtre ExceptionTranslationFilter est chargé de détecter 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 standard, il est fréquent de renseigner la propriété authenticationEntryPoint, ce qui aura pour effet de réorienter toutes les requêtes non autorisées vers une page d'entrée (ie login).

Le filtre peut être créé avec la configuration suivante.

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

Le filtre FilterSecurityInterceptor est chargé de filtrer les URLs par profil d'utilisateur.

La création du filtre s'effectue en trois étapes :
  • Création d'un manager d'authentification
  • Création d'un manager d'accès
  • Création d'une liste d'URLs par rôle
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>
      [...]
    </filter-security-metadata-source>
  </beans:property>
</beans:bean>

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

<authentication-manager alias="authenticationManager">
  <authentication-provider user-service-ref="dbAuthProvider" >
    <password-encoder hash="md5" />
  </authentication-provider>
  <authentication-provider ref="ldapAuthProvider">
    <password-encoder hash="plaintext" />
  </authentication-provider>
</authentication-manager>

On définit une liste de providers qui seront appelés dans l'ordre dans lesquels ils sont définis dans le fichier XML. 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>. Ci-dessous sont présentés des exemples d'URLs filtrées.

<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')" />

mercredi 9 juillet 2014

Un peu de lumière sur JPA et Hibernate

Comment on en est arrivé là...


"Eh les gars, il est temps de passer à JPA maintenant ! Hibernate c'est fini !".

JPA quoi ?! Java Persistence Architecture API ? Un super nouveau méga système révolutionnaire du mapping objet ?! 

En écoutant cet étrange personnage nous présenter son système de persistance, on comprend qu'il très vite s'agit d'une spécification et non d'une implémentation, et qu'il faudrait quand même continuer nos devs avec Hibernate mais avec des contraintes différentes...

Alors à quoi bon changer de système si ça fait la même chose ? Eh bien, pour participer enfin à la standardisation des interfaces dans les ORM Java !

Mais à ma connaissance Hibernate est sorti au début du siècle (en 2001...). Sur quoi donc se basait-il à l'époque ? En fouillant sur le site officiel d'Hibernate, on découvre que Gavin King avait développé son propre système de persistance afin de proposer les mêmes fonctionnalités que le système d'EJB2 mais avec une complexité moindre.

Quelques années plus tard, au vu de la floraison d'implémentations d'ORM, il semblait urgent de définir un socle unifié, d'où la sortie de JPA1.0 en 2006, mis à jour en 2009 avec JPA2.0.

2010 est l'année de sortie de la version 3.x d'Hibernate, qui est une implémentation certifié de JPA2.0.

Voila pour la petite histoire de JPA...

JPA en quelques mots


JPA2 est bien une spécification, et non une implémentation. Et sans implémentation il est impossible d'exécuter notre programme, et donc d'effectuer des appels en base (embêtant tout de même...)

Par exemple JPA définie les interfaces :

public interface JPA {
public void insert(Object obj);
public void update(Object obj);
public void delete(Object obj);
public Object select();
}

mais ne définit les implémentations, c'est à dire le code qui implémente les méthodes de ces interfaces.

Depuis sa version 3.2, Hibernate fournit une implémentation de JPA

En réalité il existe de nombreuses implémentations de JPA. Parmi celles-ci Hibernate, Toplink Essentials, Openjpa, Eclipselink, etc. Mais Hibernate est de loin la plus utilisée dans le monde java.

Il est possible d'utiliser les librairies d'Hibernate sans JPA. Le choix d'utiliser JPA force les développeurs à suivre les spécifications JPA. Par exemple les imports du type
org.hibernate.xxx
sont supprimés et sont remplacés par les imports de l'API JPA
javax.persistence.xxx

Les objets de type hibernateTemplate sont supprimés et sont remplacés par des EntityManager de JPA.
etc...
Bref, tout est standardisé !
Au runtime, il suffit d'inclure le jar de l'implémentation désirée, et c'est parti ! (pratique...)

Pour terminer, JPA n'est pas la seul spécification qui existe pour définir les concepts de persistence.
Une autre célèbre spécification en java se prénomme JDO pour Java Data Objects. A la différence de JPA, elle définit des solutions pour de la persistence vers des systèmes non-RDBMS (ex : LDAP, XML, ODF, Excel etc)

En pratique

On va donc chercher les dépendances de JPA pour les coller dans notre projet Java.

Pour les mavenistes, on colle la dépendance suivante dans notre pom.xml

<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0</version>
</dependency>

On met à jour nos imports, nos annotations, nos appels dans nos DAO, nos HQL (le language HQL est remplacé par du JPQL, plus strictes). Et hop le code compile !

Au runtime, on ajoute notre implémentation d'hibernate dans notre projet a déployer.

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>3.5.1-Final</version>
</dependency>

Eh voila, vous êtes devenus JPA compliant !




dimanche 15 juin 2014

Debug à distance avec Eclipse

Un beau jour vous rencontrez des bugs sur une application déployée sur un serveur loin mais alors très loin, alors que tout fonctionne parfaitement sur votre poste en local =/

Dans ce contexte, la résolution de bug peut s'avérer très chronophage, voir impossible. Vous aurez alors besoin d'utiliser le debug à distance !

Pour cela, suivez les étapes ci-dessous :
  1. Lancer votre serveur en mode debug
  2. Lancer votre IDE en mode debug, en pointant sur l'application déployée
  3. Débugguer comme il vous plait !

Lancement du serveur en mode debug


Pour lancer votre serveur en mode debug, ajouter les paramètres suivant à la JVM
-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n

Sous tomcat, vous pouvez ajouter la ligne suivante au fichier catalina.bat
set DEBUG_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,address=1044,server=y,suspend=n

Sous Weblogic, vous pouvez ajouter la ligne suivante au fichier startWSL.cmd
set DEBUG_OPTS = -Xdebug -Xrunjdwp:transport= dt_socket,address=1044,server=y,suspend=n
puis ajouter la variable %DEBUG_OPTS% après "%JAVA_HOME%\bin\java" dans votre script de lancement.

Jetons un oeil aux paramètres de l'option -Xrunjdwp :

  • transport=dt_socket : Définit le mode de connexion à la JVM, dans ce cas en utilisant un socket
  • server=y : Si 'y', la JVM se met en écoute sur le port précisé par l'argument 'adress'. Si 'n', la JVM essayera de se connecter au débuggeur à l'adresse précisée par l'argument 'adress'
  • suspend=n : Si 'y', le serveur se met en pause jusqu'à l'arrivée d'une connexion par un débuggeur (utile pour débugguer au démarrage, on peut aussi fixer un timeout pour attendre le débuggeur).
  • address=1044 : Numéro du port TCP/IP en écoute/sur lequel se connecter

Lancement de l'IDE en mode debug


Sous Eclipse, allez dans Debug -> Debug Configurations -> Remote Java Application. Ajouter une remote application à l'aide d'un clic-droit -> new. Préciser le nom du projet à débugguer, ainsi que l'adresse et le port d'écoute de la JVM. Cliquez sur 'Debug'.

Vous pouvez désormais débugguer comme à votre habitude en local !

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')" />

jeudi 29 mai 2014

Installer et configurer un serveur Apache

Apparu en 1995, Apache est devenu le serveur HTTP le plus populaire au monde. Dans le jargon des informaticiens, un serveur apache est un service Unix ou Windows nommé http ou apache2 installé sur une machine. De base, ce service ne fait pas grand chose, il est juste conçu pour répondre à des requêtes HTTP et retourner du contenu aux clients. La force d'Apache réside dans sa capacité à supporter de nombreux modules additionnels permettant de supporter les requêtes cryptées en SSL et d'interpréter tout un tas de langages de programmation tel que Perl, PHP, Python ou Ruby et d'héberger ainsi des sites web dynamiques.

Si cela vous intéressé, vous trouverez la liste des modules officiels sur  httpd.apache.org/docs/current/fr/mod/

Dans les lignes qui suivent, on va découvrir la simplicité avec laquelle on installe un serveur apache sous Linux et comment on le configure pour y héberger notre site web.

Installation

Nous utiliserons le gestionnaire de paquets APT pour installer notre serveur. Il est disponible sur la plupart des distributions Debian dont Ubuntu. De cette manière on ne se cassera pas la tête avec les dépendances.

Dans un console, copiez la commande suivante

sudo apt-get install apache2

Une fois l'installation terminée, on vérifie que le service est en route avec

/etc/init.d/apache2 status

Si tout va bien, vous devriez obtenir une réponse du type

Apache2 is running (pid 2410).

Si ce n'est pas le cas, redémarrez le service

/etc/init.d/apache2 restart

Et jetez un œil aux fichiers de log, il peuvent être riche d'informations surtout en cas d'échec =) (/var/log/apache2/)

En fonction de votre distribution, le service Apache peut s'appeler apache2 ou httpd

A cette étape, votre serveur Apache est fonctionnel et en tapant http://localhost dans votre navigateur, vous découvrirez une belle page comme celle-ci



Qui vous précise que votre serveur fonctionne à merveille.

Par défaut le document root du serveur est /var/www. Vous pouvez donc ajouter vos fichiers html, css, et autres dans ce répertoire et y accéder avec l'adresse localhost/nomDeMonFichier.html.

Allons un peu plus loin...


Un peu de configuration

Les fichiers de configuration du serveur Apache sont placés par défaut dans /etc/apache2

  • apache2.conf

C'est le fichier de configuration principal de votre serveur Apache.
Les principales options de ce fichier sont les suivantes :
    • Timeout X : Nb de secondes avant de retourner un timeout au client
    • LogLevel : Niveau de log émise par le serveur
    • Include mods-enabled/*.load|conf :  Charger ou non les configurations des modules
    • Include sites-enabled/ : Charger ou non les configurations des hôtes virtuels
Pour la liste complète des options, allez voir http://httpd.apache.org/docs/2.2/fr/configuring.html

  • ports.conf

Ce fichier contient la liste des ports sur lequel votre serveur écoute.

Par défaut 80 pour les requêtes non sécurisées, 443 pour les requêtes sécurisées (HTTPs).

  • sites-enabled/ et sites-available/

Le répertoire sites-available/ contient un sous répertoire par hôte virtuel. Ce répertoire contient l'ensemble des ressources mises à disposition des clients. 

Le répertoire sites-enabled/ contient un lien symbolique par virtual host. Chacun des liens pointant vers un sous répertoire de sites-available/

Pour être activé, un vhost doit posséder à la fois son répertoire dans sites-available/ et son lien symbolique dans sites-enabled/.

La commande a2ensite nomDuSite permet de créer automatiquement ce lien symbolique.
La commande a2dissite nomDuSite permet de le supprimer et ainsi de désactiver le site.

  • mods-enabled et mods-available

mods-available/ contient l'ensemble des modules rattachés au serveur. Par défaut une liste de modules sont présents tels que le core, mpm_common, event, etc. De nombreux modules optionnels existent permettant de limiter la bande passante, de faire de l'url rewriting, de supporter les scripts cgi,etc.

mods-enabled/ contient un lien symbolique par module activé. Chacun des liens pointant vers un module situé dans mods-available/.

De manière analogue aux hôtes virtuels, il existe les commandes a2enmod et  a2dismod pour activer et désactiver les modules.


Plusieurs sites sur un même serveur ? 

Vous souhaitez héberger un second site sur votre apache ? Les virtualhost sont là pour ça !

Imaginons que vous souhaitiez héberger http://sitedetata et http://sitedetonton

Pour cela, créez un fichier sitedetata.conf dans sites-available/ et copiez-y le contenu suivant

<VirtualHost *:80>
    DocumentRoot "/home/ben/mes_sites/sitedetata"
    ServerName sitedetata
    ErrorLog /var/log/error_log_du_site_de_tata

<Directory "/home/ben/mes_sites/sitedetata">
    Options Indexes FollowSymLinks Includes
    AllowOverride All
    Order allow,deny
    Allow from all
</Directory>
</VirtualHost>

DocumentRoot définit l'emplacement du répertoire racine du site, ici /home/ben/mes_sites/sitedetata.
ServerName correspond au nom de domaine de votre nouveau site en local (http://sitedetata)

Utilisez ensuite la commande a2ensite

sudo a2ensite sitedetata.conf

De manière à créer le lien symbolique dans le répertoire sites-enabled/ puis recharger la configuration de votre serveur apache

sudo service apache2 reload

Ouvrez votre navigateur et rendez vous sur http://sitedetata, votre site est accessible !

Il ne vous reste plus qu'à recommencer pour votre second site http://sitedetonton.