41 votes

Sécurisation de l'API REST sur le framework Play et OAuth2

Je développe une application avec Play 2.0 et Scala qui expose une API REST. Ces API seront utilisées par différentes applications, web, mobiles ou de bureau, et le protocole OAuth (OAuth2) semble donc le plus approprié.

De même, j'utiliserais initialement un fournisseur OAuth externe tel que Facebook.

Ma question est la suivante : quel est le flux exact pour autoriser l'appel REST individuel ? Que dois-je attendre du côté du serveur pour chaque appel et que dois-je vérifier auprès du fournisseur externe ?

Avec OAuth1, je savais que le client envoyait le jeton avec toutes les demandes signées, mais avec Oauth2, je ne pense pas, j'imagine que si un jeton n'est pas signé, il n'est pas fiable et donc je ne pense pas que ce soit le flux.

17voto

Rakesh Waghela Points 780

Vous pouvez utiliser un module appelé SecureSocial.

https://github.com/jaliss/securesocial/

Celui-ci est assez raffiné et de nombreuses personnes de la communauté Play semblent connaître/utiliser ce module.

Pour l'autorisation pourrait être utile. https://github.com/schaloner/deadbolt-2/

Pour des trucs scala de bout en bout, https://github.com/t2v/play20-auth

16voto

Clean Yong Points 161

J'ai porté Apache Amber vers Play2 Scala, voici le lien : https://github.com/cleanyong/oauth2play2scala

La raison de porter Apache Amber est :

  1. il a été testé
  2. mieux que le fait maison
  3. il s'adapte à l'API Scala de Play2
  4. facile à utiliser
  5. pas intrusif

Si vous voulez installer un serveur oauth2 sur votre site, vous pouvez essayer d'utiliser mon port. Il a un document.

7voto

nico_ekito Points 13977

Fondamentalement, le flux standard est le suivant :

  1. à chaque requête, vérifier dans le cookie ("session" dans le dialecte Play !) s'il contient un id
  2. si non, demander à l'utilisateur de s'authentifier auprès du fournisseur (Facebook ou autre)
  3. S'il est correct, le fournisseur renverra un identifiant, enregistrera cet identifiant dans votre système de persistance (enregistrement) et dans le cookie/session actuel.
  4. lors des prochaines requêtes, vérifiez si l'identifiant existe dans le cookie/session et correspond à un utilisateur existant dans votre système de persistance.
  5. Pour se déconnecter, il suffit d'effacer le cookie/session.

Si vous voulez plus de détails, n'hésitez pas à demander :-)

4voto

Abhishek Tyagi Points 488

OAuth est un protocole d'autorisation, donc si vous cherchez une solution d'authentification, ce n'est peut-être pas la bonne.

Votre question dit que le consommateur de l'API sera diverses applications. Cela conduit à 2 scénarios,

 1. Where there is no end user involved (grant_type: client_credential)  
 2. Where end-user can consume these APIs on multiple Application (Owned by your Org) (grant_type: implicit/password)
 3. Where end-user can consume these APIs via third Party Applications.(authrization_code)

Pour supporter l'éco-système OAuth, vous avez besoin d'un système de gestion des clés. Pour,

  1. Générer des clés/secrets pour les applications.
  2. Génération de l'AccessToken/Refresh_token/autorisation_code

Maintenant, pour en venir au point de terminaison, vous devez l'exposer,

3-Legged OAuth
GET     /authorize  authorize{entry point/ initiate oauth}  
    Sample Call: http://YourAPIService.com/authorize?response_type=code&client_id=GG1IbStzH45ajx9cEeILqjFt&scope=READ&redirect_uri=www.google.com

    GET     /login  login (Call Page for login App, 302 redirected from /authorize)     
Sample Call: http://YourAPIService.com/v1/oauth20/login?response_type=code&client_id=GG1IbStzH45ajx9cEeILqjFt&scope=READ&redirect_uri=www.google.com

    POST    /dologin    consentPage     http://YourAPIService.com/dologin 
    Submit the credential, On success, render the application page 

    POST    /grantpermission    consentSubmission   http://YourAPIService.com/grantpermission
Permission has been granted/declined. Send a 302 to generate authorization_code 

    GET      /code          AuthorizationCode {To generate auth code}
    Sample Call: http://YourAPIService.com/code?client_id=GG1IbStzH45ajx9cEeILqjFt&response_type=code&user_id=user@YourAPIService.com&redirect_uri=www.google.com

    POST    /token  GenerateAccessToken     http://YourAPIService.com/token 
Sample call: http://kohls-test.mars.apigee.net/v1/oauth20/token
Header: Authorization: Basic R0cxSWJTdHpINDVhang5Y0VlSUxxalFj its generated with apps Api Key & Secret.
Payload: 
grant_type=authorization_code&scope=x&redirect_uri=www.google.com&code=abc123

Autrement, la solution la plus simple/robuste serait, http://apigee.com

Vous pouvez utiliser l'écosystème OAuth existant d'Apigee.

0voto

julianromera Points 401

J'ai eu le même problème, ce que j'ai fait (je suppose que ce n'est pas la meilleure solution), c'est de placer les méthodes du serveur REST, à l'intérieur d'un "@Security.Authenticated(Secure.class)", et, d'utiliser un cookie de session (qui a également été enregistré dans une table de hachage dans le backend). Le cookie de session est généré après la signature de l'utilisateur

I post code:

package controllers;

import ...;

@Security.Authenticated(Secured.class)
public class ExampleController extends Controller {

    public static String currentUserEmail() {

 ... return json after checking that 'session("id")' exists in the loggedin users hash table... 

}

et

package controllers;

import ...;

public class Secure extends Security.Authenticator {

    @Override
    public String getUserId(Http.Context context) {
        return context.session().get("user_id");
    }
...
}

J'espère que cela vous aidera

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X