IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Services Web Java Discussion :

Identification pour utilisation de services rests


Sujet :

Services Web Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    174
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 174
    Par défaut Identification pour utilisation de services rests
    Bonjour,
    J'aimerais faire un site internet avec du html/angularJS en front-end et du java en back-end (services REST).

    Je voudrais gérer une authentification pour que seuls les utilisateurs habilités puissent utiliser leurs services correspondants. Quand j'avais fais du PHP on utilisait des variables de session qui était détruites quand le navigateur était fermé mais je ne sais pas comment faire en java. En gros il faudrait ceci:
    - L'utilisateur s'authentifie (cela initialiserait une session)
    - L'utilisateur appelle des services REST (controle de ses droits avec la session pour vérifier qu'il peut l'appeler).

    J'ai vu qu'avec Tomcat on a des sessions.

    On peut tester si une session existe avec un code comme ceci dans un filtre (classe qui implémente Filter):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public void doFilter (ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
         if (((HttpServletRequest)request).getSession(true).getAttribute("utilisateur.valide" )!=null) {
            chain.doFilter(request, response);
         } else {
            ((HttpServletResponse)response).sendRedirect("/connexion.jsp" );
        }
    }
    Et en déclarant le filtre dans le web.xml.

    Ensuite dans le code java on peut récupérer la session avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    HttpSession session = request.getSession();
    Est-on obligé de passer par une JSP forcément pour pouvoir manipuler la session dans la page car de ce que j'ai compris la session n'est que côté serveur? (par exemple si j'y stocke le nom utilisateur pour ensuite l'afficher sur toutes les pages).

    La session sera accessible ensuite pour chaque service REST pour tester les droits de l'utilisateur que je compte mettre dedans?

    Je vous remercie d'avance.

  2. #2
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 326
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 326
    Billets dans le blog
    12
    Par défaut
    Bonjour,

    J'ai vu qu'avec Tomcat on a des sessions.
    Les sessions font partie de la norme Java EE, tu remarqueras que le package de la classe HttpSession commence par javax.. Tomcat n'est que le container de servlet qui implémente cette norme

    Est-on obligé de passer par une JSP forcément pour pouvoir manipuler la session dans la page car de ce que j'ai compris la session n'est que côté serveur? (par exemple si j'y stocke le nom utilisateur pour ensuite l'afficher sur toutes les pages).
    La session est une technologie serveur. Il est conseillé de manipuler l'objet HttpSession dans un filter ou une servlet (le contrôleur), plutôt que dans une JSP (la vue) même si c'est possible, afin de respecter le MVC. Dans ton cas tu souhaites utiliser du REST... par contre ce dernier repose sur une architecture SOA stateless (sans état), tu dois donc trouver un moyen d'injecter ta session dans la méthode, exemple :
    Code Java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    @GET
    public String get(@Context HttpServletRequest request) {
        HttpSession session = request.getSession();
        return "OK";
    }

    La session sera accessible ensuite pour chaque service REST pour tester les droits de l'utilisateur que je compte mettre dedans?
    Cette étape de vérification se passe avant d'accéder à REST.

    Cordialement,
    N'hésitez pas à consulter la FAQ Java, lire les cours et tutoriels Java, et à poser vos questions sur les forums d'entraide Java

    Ma page Developpez | Mon profil Linkedin | Vous souhaitez me contacter ? Contacter Gokan EKINCI

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    174
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 174
    Par défaut
    Bonjour et merci pour ton retour.

    Effectivement j'ai fais un abus de langage pour Tomcat^^.

    Quand tu dis "Cette étape de vérification se passe avant d'accéder à REST", qu'entends-tu par là?

    C'est dans ma page que je vais avoir un appel au REST de type "http://localhost:8080/MonAppliRest/personnes/get/1" et coté serveur j'aurais un contrôleur déclaré avec @RestController:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    @RestController
    public class PersonnesController {
     
        @RequestMapping("/personnes/get/{id}")
        public Personne getPersonne(@PathVariable(value="id") String id) {
            Personne personne;
     
            // on récupère la personne en fonction de l'id voulu
     
            return personne;
        }
    }
    A quel moment puis-je vérifier qu'il a les droits d'accéder à ce service (selon son profil je ne souhaite pas qu'il puisse appeler certains services par exemple)?

    Il me faudrait contrôler côté serveur ses droits en fonction de son profil pour retourner une erreur s'il n'a pas la permission.

    Pour l'identification de l'utilisateur, quels sont les moyens à ma disposition pour ma configuration d'appel à du REST par du HTML/AngularJS (à part une jsp qui, à la validation du formulaire, provoquerait un appel à une vérification de l'association mail/mot de passe et à l'initialisation de la session avec ses droits puis à une utilisation de cette session pour contrôler l'accès aux services comme je pensais faire après avoir vu des exemples mais qui ne portaient pas sur du REST)?

    PS: sur un projet où j'ai été il y avait utilisation d'un token pour identifier l'utilisateur qui était passé dans le header de la requête HTTP REST il me semble mais je n'ai pas eu l'occasion de travailler sur cette partie donc je ne sais pas comment cela avait été mis en place. C'est peut être ce principe que je dois utiliser?

    Edit: j'ai peut-être trouvé un élément de réponse ici sur l'utilisation de tokens: http://blog.inovia-conseil.fr/?p=236, http://blog.ineat-conseil.fr/2013/01...uthentication/ ou encore http://stackoverflow.com/questions/2...-rs-and-jersey

  4. #4
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 326
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 326
    Billets dans le blog
    12
    Par défaut
    Bonjour,

    Ah ben tu fais du Spring MVC
    Pour répondre à ta question, je reprends le contexte : "chaque méthode REST pour tester les droits" une architecture RESTful tu y as accès via une URL, c'est publique, n'importe quel utilisateur peut y accéder, tu ne testes donc pas dedans, tu trouves le moyen de tester avant.

    Je pense que tu es sur la bonne voie avec les tokens. Si tu as une question n'hésite pas, si tes sujets sont résolus, n'hésite pas à les mettre en résolu

    Cordialement,
    N'hésitez pas à consulter la FAQ Java, lire les cours et tutoriels Java, et à poser vos questions sur les forums d'entraide Java

    Ma page Developpez | Mon profil Linkedin | Vous souhaitez me contacter ? Contacter Gokan EKINCI

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    174
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 174
    Par défaut
    Bonjour,
    Je suis en train de tester ce qui est expliqué ici: http://stackoverflow.com/questions/2...-rs-and-jersey

    J'essaye de transposer à mon contexte car il y a une notion de role et en fonction on autorise ou refuse avec un filtre et c'est pile ce que je veux.

    Je n'arrive pas à lancer le serveur.

    Voici le pom.xml:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
     
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>TestAngularRestToken</groupId>
      <artifactId>TestAngularRestToken</artifactId>
      <packaging>war</packaging>
      <version>0.0.1-SNAPSHOT</version>
      <name>TestAngularRestToken Maven Webapp</name>
      <url>http://maven.apache.org</url>
      <dependencies>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>3.8.1</version>
          <scope>test</scope>
        </dependency>
     
        <dependency>
    		<groupId>javax.servlet</groupId>
    		<artifactId>servlet-api</artifactId>
    		<version>2.5</version>
    		<scope>compile</scope>
    	</dependency>
     
        <!-- Utilisation de cette bibliothèque pour jeton JWT -->
     
        <dependency>
    	    <groupId>io.jsonwebtoken</groupId>
    	    <artifactId>jjwt</artifactId>
    	    <version>0.7.0</version>
    	</dependency>
     
    	<!-- Pour utilisation de MVC avec Spring -->
     
    	<dependency>
    		<groupId>org.springframework</groupId>
    		<artifactId>spring-webmvc</artifactId>
    		<version>4.1.0.RELEASE</version>
    	</dependency>
     
    	<!-- Pour utilisation de jersey -->
     
    	<dependency>
    		<groupId>org.glassfish.jersey.ext</groupId>
    		<artifactId>jersey-spring3</artifactId>
    		<version>2.14</version>
    		<exclusions>
    			<exclusion>
    				<groupId>org.springframework</groupId>
    				<artifactId>spring-core</artifactId>
    			</exclusion>
    			<exclusion>
    				<groupId>org.springframework</groupId>
    				<artifactId>spring-web</artifactId>
    			</exclusion>
    			<exclusion>
    				<groupId>org.springframework</groupId>
    				<artifactId>spring-beans</artifactId>
    			</exclusion>
    		</exclusions>
    	</dependency>
     
    	<dependency>
    		<groupId>org.glassfish.jersey.media</groupId>
    		<artifactId>jersey-media-json-jackson</artifactId>
    		<version>2.14</version>
    		<exclusions>
    			<exclusion>
    				<groupId>com.fasterxml.jackson.jaxrs</groupId>
    				<artifactId>jackson-jaxrs-base</artifactId>
    			</exclusion>		
    			<exclusion>
    				<groupId>com.fasterxml.jackson.core</groupId>
    				<artifactId>jackson-annotations</artifactId>
    			</exclusion>
    			<exclusion>
    				<groupId>com.fasterxml.jackson.jaxrs</groupId>
    				<artifactId>jackson-jaxrs-json-provider</artifactId>
    			</exclusion>        					
    		</exclusions>
    	</dependency>
     
    	<dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet-core</artifactId>
            <version>2.14</version>
        </dependency>
     
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet</artifactId>
            <version>2.14</version>
        </dependency>
     
        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-server</artifactId>
            <version>2.14</version>
        </dependency>
     
    	<!-- Pour interraction BD -->
     
    	<dependency>
    		<groupId>org.hsqldb</groupId>
    		<artifactId>hsqldb</artifactId>
    		<version>2.3.1</version>
    	</dependency>
     
    	<dependency>
    		<groupId>org.springframework</groupId>
    		<artifactId>spring-orm</artifactId>
    		<version>4.1.0.RELEASE</version>
    	</dependency>
     
    	<dependency>
    		<groupId>org.hibernate</groupId>
    		<artifactId>hibernate-entitymanager</artifactId>
    		<version>4.3.4.Final</version>
    	</dependency>
      </dependencies>
      <build>
        <finalName>TestAngularRestToken</finalName>
      </build>
    </project>
    Voici le contenu de web.xml dans lequel j'ai déclaré une servlet pour Spring et une pour Jersey :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
     
    <web-app>
      <display-name>Archetype Created Web Application</display-name>
     
      <!-- On indique qu'un fichier dispatcher-servlet.xml contient une configuration du contexte -->
      <context-param>
    	<param-name>contextConfigLocation</param-name>
    	<param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
      </context-param>
     
      <!-- On indique le listener pour le contexte de Spring -->
      <listener>
    	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>
     
      <!-- Declaration de la servlet DispatcherServlet de Spring et de son mapping 
      (intercepte n'importe quelle URL et réoriente vers les controlleurs déclarés dans Spring correspondants) -->
      <servlet>
    	<servlet-name>servlet-dispatcher</servlet-name>
    	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    	<!-- Utilisation des beans définis dans dispatcher-servlet.xml -->
    	<init-param>
    		<param-name>contextConfigLocation</param-name>
    		<param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
    	</init-param>
    	<load-on-startup>1</load-on-startup>
      </servlet>
     
      <!-- Déclaration de la servlet pour jersey qui est chargée en second -->
      <servlet>
    	<servlet-name>jersey-serlvet</servlet-name>
    	<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    	<init-param>
       		<param-name>jersey.config.server.provider.packages</param-name>
                    <param-value>com.testAngularRestToken</param-value>
            </init-param>
    	<load-on-startup>2</load-on-startup>
      </servlet>
     
      <servlet-mapping>
    	<servlet-name>servlet-dispatcher</servlet-name>
    	<url-pattern>/</url-pattern>
      </servlet-mapping>
     
      <servlet-mapping>
    	<servlet-name>jersey-serlvet</servlet-name>
    	<url-pattern>/rest/*</url-pattern>
      </servlet-mapping>
      
      <!-- Declaration de l'utilisation de la ressource JDBC définie dans le serveur Tomcat
      ("jdbc/dsMonApplication" est le nom mis dans le lien pour la ressource dans le context.xml
      du serveur Tomcat). -->
    	<resource-ref>
    		<description>Ressource JDBC de l'application</description>
    		<res-ref-name>jdbc/dsMonApplication</res-ref-name>
    		<res-type>javax.sql.DataSource</res-type>
    		<res-auth>Container</res-auth>
    		<res-sharing-scope>Shareable</res-sharing-scope>
    	</resource-ref>
    </web-app>
    Voici le contenu du dispatcher-servlet.xml:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
     
    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.0.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
    	<!-- Active la configuration par annotations (annotations utilisées dans les controlleurs par exemple).
    	"context" est référencée par "xmlns:context=...". -->
    	<context:component-scan base-package="com.testAngularRestToken" />
     
    	<!-- Permet de scanner tous les beans (exemple: Personne qui est déclaré comme entité) dans le contexte 
    	d'application et de créer des intercepteurs AOP pour ceux qui sont annotés. "tx" est référencée par 
    	"xmlns:tx=..." -->
    	<tx:annotation-driven transaction-manager="transactionManager" />
     
    	<!-- Le bean "JndiObjectFactoryBean" permet de déclarer l'utilisation de la ressource JDBC. -->
    	<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    		<property name="jndiName" value="java:comp/env/jdbc/dsMonApplication" />
    	</bean>
     
    	<!-- Le bean "LocalContainerEntityManagerFactoryBean" utilise la ressource JDBC et le fichier "persistence.xml" 
    	pour aboutir à la création du "EntityManager" qui est utilisé dans la DAO -->
    	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    		<property name="dataSource" ref="dataSource" />
    	</bean>
     
    	<!-- Le bean "JpaTransactionManager" permet d'instancier le gestionnaire de transaction et lui associer la 
    	fabrique de "EntityManager" -->
    	<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    		<property name="entityManagerFactory" ref="entityManagerFactory" />
    	</bean>
    </beans>
    Quand je démarre le serveur j'ai l'erreur suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    java.lang.ClassNotFoundException: jersey.repackaged.com.google.common.base.Function
    Je pense que j'ai une couille quelque part. Soit il me manque une dépendance dans le pom.xml, soit elles ne sont pas correctes ou bien le contenu du web.xml est incorrect (je ne suis pas sur du contenu de <init-param> pour "jersey-serlvet").

    Pouvez-vous m'aider svp?

    Edit: J'avais essayé en mettant ceci dans pom.xml mais cela ne résolvait pas le problème:
    <dependency>
    <groupId>org.glassfish.jersey.bundles.repackaged</groupId>
    <artifactId>jersey-guava</artifactId>
    <version>2.14</version>
    </dependency>

    Mais avec la version 2.13 cela fonctionne. Allez savoir pourquoi...

    Tout semble fonctionner (je mettrais un exemple de code plus tard une fois tout terminé pour que d'autres personnes puissent avoir un exemple).

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    174
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 174
    Par défaut
    Bonjour,
    J'ai terminé le code pour la mise en place de token et de filtre en utilisant jersey combiné avec spring mvc. Je mettrais l'exemple le week-end prochain si j'ai le temps.

    J'ai essayé aujourd'hui de faire une autre version sans utiliser jersey. J'ai donc voulu utiliser spring-security pour faire à peu près la même chose (identification et création d'un token puis vérification de ce token pour chaque service).

    J'ai suivi les explications ici: https://www.toptal.com/java/rest-sec...urity-and-java

    Voici le contenu de mon pom.xml:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
     
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>TestAngularRestToken</groupId>
      <artifactId>TestAngularRestToken</artifactId>
      <packaging>war</packaging>
      <version>0.0.1-SNAPSHOT</version>
      <name>TestAngularRestToken Maven Webapp</name>
      <url>http://maven.apache.org</url>
      <dependencies>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>3.8.1</version>
          <scope>test</scope>
        </dependency>
     
        <dependency>
    		<groupId>javax.servlet</groupId>
    		<artifactId>servlet-api</artifactId>
    		<version>2.5</version>
    		<scope>compile</scope>
    	</dependency>
     
        <!-- Utilisation de cette bibliothèque pour jeton JWT -->
     
        <dependency>
    	    <groupId>io.jsonwebtoken</groupId>
    	    <artifactId>jjwt</artifactId>
    	    <version>0.7.0</version>
    	</dependency>
     
    	<!-- Utilisation de Spring (on indique ici toutes les dépendances car spring-security contient aussi 
    	des dépendances vers des jars de Spring - exemple: spring-core est référencée par spring-orm dans une 
    	version 4.x ici mais aussi par spring-security-core dans sa version 3.2.x ici - donc en les indiquant 
    	on indique explicitement quelle version Maven va considérer) -->
     
    	<dependency> 
    	    <groupId>org.springframework</groupId> 
    	    <artifactId>spring-core</artifactId> 
    	    <version>4.1.0.RELEASE</version> 
    	</dependency> 
     
    	<dependency> 
    	    <groupId>org.springframework</groupId> 
    	    <artifactId>spring-context</artifactId> 
    	    <version>4.1.0.RELEASE</version> 
    	</dependency> 
     
    	<dependency> 
    	    <groupId>org.springframework</groupId> 
    	    <artifactId>spring-jdbc</artifactId> 
    	    <version>4.1.0.RELEASE</version> 
    	</dependency> 
     
    	<dependency> 
    	    <groupId>org.springframework</groupId> 
    	    <artifactId>spring-beans</artifactId> 
    	    <version>4.1.0.RELEASE</version> 
    	</dependency> 
     
    	<dependency> 
    	    <groupId>org.springframework</groupId> 
    	    <artifactId>spring-aop</artifactId> 
    	    <version>4.1.0.RELEASE</version> 
    	</dependency> 
     
    	<dependency> 
    	    <groupId>org.springframework</groupId> 
    	    <artifactId>spring-tx</artifactId> 
    	    <version>4.1.0.RELEASE</version> 
    	</dependency> 
     
    	<dependency> 
    	    <groupId>org.springframework</groupId> 
    	    <artifactId>spring-expression</artifactId> 
    	    <version>4.1.0.RELEASE</version> 
    	</dependency> 
     
    	<dependency> 
    	    <groupId>org.springframework</groupId> 
    	    <artifactId>spring-web</artifactId> 
    	    <version>4.1.0.RELEASE</version> 
    	</dependency>
     
    	<dependency>
    		<groupId>org.springframework</groupId>
    		<artifactId>spring-webmvc</artifactId>
    		<version>4.1.0.RELEASE</version>
    	</dependency>
     
    	<!-- Utilisation de Spring Security -->
     
    	<dependency>
    	    <groupId>org.springframework.security</groupId>
    	    <artifactId>spring-security-core</artifactId>
    	    <version>4.0.0.RELEASE</version>
    	</dependency>
     
    	<dependency>
    		<groupId>org.springframework.security</groupId>
    		<artifactId>spring-security-web</artifactId>
    		<version>4.0.0.RELEASE</version>
    	</dependency>
     
    	<dependency>
    		<groupId>org.springframework.security</groupId>
    		<artifactId>spring-security-config</artifactId>
    		<version>4.0.0.RELEASE</version>
    	</dependency>
     
    	<!-- Pour interraction BD -->
     
    	<dependency>
    		<groupId>org.hsqldb</groupId>
    		<artifactId>hsqldb</artifactId>
    		<version>2.3.1</version>
    	</dependency>
     
    	<dependency>
    		<groupId>org.springframework</groupId>
    		<artifactId>spring-orm</artifactId>
    		<version>4.1.0.RELEASE</version>
    	</dependency>
     
    	<dependency>
    		<groupId>org.hibernate</groupId>
    		<artifactId>hibernate-entitymanager</artifactId>
    		<version>4.3.4.Final</version>
    	</dependency>
      </dependencies>
      <build>
        <finalName>TestAngularRestToken</finalName>
      </build>
    </project>
    Voici le contenu du web.xml:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
     
    <!DOCTYPE web-app PUBLIC
     "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
     "http://java.sun.com/dtd/web-app_2_3.dtd" >
     
    <web-app>
      <display-name>Archetype Created Web Application</display-name>
     
      <!-- On indique qu'un fichier dispatcher-servlet.xml contient une configuration du contexte -->
      <context-param>
    	<param-name>contextConfigLocation</param-name>
    	<param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
      </context-param>
     
      <!-- Filtre de sécuité (appelé à chaque fois que l'URL de mapping est rencontrée). Le nom
      doit être exactement "springSecurityFilterChain". -->
      <filter>
    		<filter-name>springSecurityFilterChain</filter-name>
    		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
      </filter>
      <filter-mapping>
    		<filter-name>springSecurityFilterChain</filter-name>
    		<url-pattern>/rest/*</url-pattern>
      </filter-mapping>
      
      <!-- On indique le listener pour le contexte de Spring -->
      <listener>
    	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>
      
      <!-- Declaration de la servlet DispatcherServlet de Spring et de son mapping 
      (intercepte n'importe quelle URL et réoriente vers les controlleurs déclarés dans Spring correspondants) -->
      <servlet>
    	<servlet-name>servlet-dispatcher</servlet-name>
    	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    	<!-- Utilisation des beans définis dans dispatcher-servlet.xml -->
    	<init-param>
    		<param-name>contextConfigLocation</param-name>
    		<param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
    	</init-param>
    	<load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
    	<servlet-name>servlet-dispatcher</servlet-name>
    	<url-pattern>/rest/*</url-pattern>
      </servlet-mapping>
      
      <welcome-file-list>
            <welcome-file>index.html</welcome-file>
      </welcome-file-list>
      
      <!-- Declaration de l'utilisation de la ressource JDBC définie dans le serveur Tomcat
      ("jdbc/dsMonApplication" est le nom mis dans le lien pour la ressource dans le context.xml
      du serveur Tomcat). -->
    	<resource-ref>
    		<description>Ressource JDBC de l'application</description>
    		<res-ref-name>jdbc/dsMonApplication</res-ref-name>
    		<res-type>javax.sql.DataSource</res-type>
    		<res-auth>Container</res-auth>
    		<res-sharing-scope>Shareable</res-sharing-scope>
    	</resource-ref>
    </web-app>
    Voici le contenu du dispatcher-servlet.xml (j'ai mis toute la configuration de spring ici mais j'ai vu des exemples qui séparent la sécurité donc je ne sais pas ce qui est correct):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
     
    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:security="http://www.springframework.org/schema/security"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.0.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
    http://www.springframework.org/schema/security
    http://www.springframework.org/schema/security/spring-security-4.0.xsd">
    	<!-- Active la configuration par annotations (annotations utilisées dans les controlleurs par exemple).
    	"context" est référencée par "xmlns:context=...". -->
    	<context:component-scan base-package="com.testAngularRestToken" />
     
    	<!-- Permet de scanner tous les beans (exemple: Personne qui est déclaré comme entité) dans le contexte 
    	d'application et de créer des intercepteurs AOP pour ceux qui sont annotés. "tx" est référencée par 
    	"xmlns:tx=..." -->
    	<tx:annotation-driven transaction-manager="transactionManager" />
     
    	<!-- Permet d'enregistrer automatiquement un HTTPMessageConverter (pour conversion de et vers JSON) -->
    	<mvc:annotation-driven />
     
    	<!-- Le bean "JndiObjectFactoryBean" permet de déclarer l'utilisation de la ressource JDBC. -->
    	<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    		<property name="jndiName" value="java:comp/env/jdbc/dsMonApplication" />
    	</bean>
     
    	<!-- Le bean "LocalContainerEntityManagerFactoryBean" utilise la ressource JDBC et le fichier 
    	"persistence.xml" pour aboutir à la création du "EntityManager" qui est utilisé dans la DAO -->
    	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    		<property name="dataSource" ref="dataSource" />
    	</bean>
     
    	<!-- Le bean "JpaTransactionManager" permet d'instancier le gestionnaire de transaction et lui associer la 
    	fabrique de "EntityManager" -->
    	<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    		<property name="entityManagerFactory" ref="entityManagerFactory" />
    	</bean>
     
    	<!-- Configuration de sping-security -->
     
    	<!-- <security:global-method-security secured-annotations="enabled" pre-post-annotations="enabled" jsr250-annotations="enabled"/> -->
    	<!-- Activation des annotations @PreFilter, @PreAuthorize, @PostFilter, @PostAuthorize sur chaque bean de 
    	Spring -->
    	<security:global-method-security pre-post-annotations="enabled" />
     
        <!-- On indique que pour "/rest/authentication", il n'y a pas de sécurité (tout le monde peut appeler pour 
        s'authentifier. -->
        <security:http pattern="/rest/authentication" security="none"/>
     
    	<!-- On indique le point d'entrée lors d'un appel à tous les services REST. 
    	"stateless" indique qu'on ne veut pas de session créée pour la sécurité vu que l'on utilise des
    	token pour chaque requête. -->
        <security:http pattern="/rest/**" entry-point-ref="restAuthenticationEntryPoint" create-session="stateless">
            <!-- Nous n'avons pas besoin de protection csrf car le token est immunisé à ca. -->
            <security:csrf disabled="true"/>
            <!-- On indique que l'on utilise un filtre customisé référencé par "jwtAuthenticationFilter" (défini 
            plus bas). Il sera placé avant le filtre pour le formulaire de login dans la chaine des filtres 
            prédéfinis dans Spring. -->
            <security:custom-filter before="FORM_LOGIN_FILTER" ref="jwtAuthenticationFilter"/>
        </security:http>
     
        <!-- On indique où se trouve notre filtre qui sera géré comme un bean par Spring. -->
        <bean id="jwtAuthenticationFilter" class="com.testAngularRestToken.filter.JwtAuthenticationFilter">
            <property name="authenticationManager" ref="authenticationManager" />
            <property name="authenticationSuccessHandler" ref="jwtAuthenticationSuccessHandler" />
        </bean>
     
         <!--  -->
        <security:authentication-manager alias="authenticationManager">
            <security:authentication-provider ref="jwtAuthenticationProvider" />
        </security:authentication-manager>
     
    </beans>
    Voici le contenu de mon filtre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
     
    package com.testAngularRestToken.filter;
     
    import java.io.IOException;
     
    import javax.servlet.FilterChain;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
     
    import org.springframework.security.core.Authentication;
    import org.springframework.security.core.AuthenticationException;
    import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
     
    public class JwtAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
     
        public JwtAuthenticationFilter() {
            super("/**");
        }
     
        @Override
        protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {
            return true;
        }
     
        @Override
        public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
     
            String authorizationHeader = request.getHeader("Authorization");
     
            if (authorizationHeader == null || !authorizationHeader.startsWith("Bearer")) {
                throw new JwtTokenAuthenticationException("No JWT token found in request headers");
            }
     
            String token = authorizationHeader.substring("Bearer".length()).trim();
     
            JwtAuthenticationToken authRequest = new JwtAuthenticationToken(token);
     
            return getAuthenticationManager().authenticate(authRequest);
        }
     
        @Override
        protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult)
                throws IOException, ServletException {
            super.successfulAuthentication(request, response, chain, authResult);
     
            // As this authentication is in HTTP header, after success we need to continue the request normally
            // and return the response as if the resource was not secured at all
            chain.doFilter(request, response);
        }
    }
    Voici le contenu de mon provider:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
     
    package com.testAngularRestToken.filter;
     
    import java.util.List;
     
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
    import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;
    import org.springframework.security.core.AuthenticationException;
    import org.springframework.security.core.GrantedAuthority;
    import org.springframework.security.core.authority.AuthorityUtils;
    import org.springframework.security.core.userdetails.UserDetails;
    import org.springframework.stereotype.Component;
     
    import com.testAngularRestToken.beans.Utilisateur;
    import com.testAngularRestToken.dao.IUtilisateursDao;
    import com.testAngularRestToken.utils.TokenUtils;
     
    //On déclare en composant pour que spring le gère (évite d'avoir à déclarer le bean dans le xml de 
    //configuration de spring).
    @Component
    public class JwtAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {
     
    	// Permet que le DAO soit setté par Spring.
    	// Explication: quand on a déclaré l'implémentation du DAO (UtilisateursDao), on a indiqué 
    	// l'annotation @Repository. Spring sait donc qu'il y a un bean UtilisateursDao qui implémente 
    	// l'interface attendue ici (IUtilisateursDao). Il va donc injecter ce bean. Si plusieurs 
    	// implémentations de l'interface existaient, alors une erreur se poduirait car Spring ne saurait pas
    	// quel bean injecter.
    	@Autowired
    	private IUtilisateursDao dao;
     
        @Override
        public boolean supports(Class<?> authentication) {
            return (JwtAuthenticationToken.class.isAssignableFrom(authentication));
        }
     
        @Override
        protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
        }
     
        @Override
        protected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
            JwtAuthenticationToken jwtAuthenticationToken = (JwtAuthenticationToken) authentication;
            String token = jwtAuthenticationToken.getToken();
     
            String usernameToken = TokenUtils.verifierToken(token);
     
            if(usernameToken.isEmpty()) {
            	throw new JwtTokenAuthenticationException("JWT token is not valid");
            }
     
            // On récupère l'utilisateur correspondant
            Utilisateur util = dao.getUtilisateur(usernameToken);
     
            List<GrantedAuthority> authorityList = AuthorityUtils.commaSeparatedStringToAuthorityList(util.getRole());
     
            return new AuthenticatedUser(util.getUsername(), authorityList);
        }
     
    }
    Voici le code de mon implémentation de AuthenticationSuccessHandler:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    package com.testAngularRestToken.filter;
     
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
     
    import org.springframework.security.core.Authentication;
    import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
    import org.springframework.stereotype.Component;
     
    // On déclare en composant pour que spring le gère (évite d'avoir à déclarer le bean dans le xml de 
    // configuration de spring).
    @Component
    public class JwtAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
     
    	// Appelé quand l'authentification est en succès
        public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
            // Rien à faire dans notre cas car il n'y a pas de page vers laquelle rediriger (il y aura juste
        	// un retour du token).
        }
     
    }
    Voici le code pour mon implémentation de AuthenticationEntryPoint:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    package com.testAngularRestToken.filter;
     
    import java.io.IOException;
     
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
     
    import org.springframework.security.core.AuthenticationException;
    import org.springframework.security.web.AuthenticationEntryPoint;
    import org.springframework.stereotype.Component;
     
    //On déclare en composant pour que spring le gère (évite d'avoir à déclarer le bean dans le xml de 
    //configuration de spring).
    @Component
    public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {
     
    	// Appelé quand un utilisateur essaye d'accéder à un service REST protégé sans être authentifié.
        public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
            // On renvoi juste une erreur 401 Unauthorized car il n'y a pas de page vers laquelle rediiger ici.
        	response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
        }
    }
    Je ne passe pas dans l'implémentation de AuthenticationEntryPoint (pose d'un point d'arrêt) et ne comprends donc pas quand c'est appelé (précision: je passe bien dans le filtre, dans le provider et dans le handler). Pouvez-vous m'expliquer svp?

    Enfin, je ne comprends pas l'intérêt de l'annotation '@PreAuthorize("isAuthenticated()")' dans mon cas sur le contrôleur car le filtre est tout de même appelé si je ne la mets pas. Pouvez-vous m'expliquer svp?

Discussions similaires

  1. Réponses: 3
    Dernier message: 21/01/2013, 17h28
  2. SQL Server 2005 et droit pour utiliser Integration Services
    Par EmmanuelleC dans le forum Administration
    Réponses: 2
    Dernier message: 27/08/2012, 10h00
  3. Réponses: 3
    Dernier message: 08/04/2011, 12h26
  4. Réponses: 1
    Dernier message: 04/06/2010, 16h38

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo