J'ai des difficultés à saisir l'idée d'autorisation dans PlayFramework (version 2.5). Ma situation est que j'ai une méthode API REST getUser
et je veux restreindre son accès en effectuant une autorisation avec un jeton qui vient dans l'en-tête de demande personnalisé nommé "X-Authorization"
. Maintenant, mon code du contrôleur ressemble que:Restriction de l'accès à la méthode dans Play Framework avec autorisation - Java
package controllers;
import models.User;
import org.bson.types.ObjectId;
import play.mvc.*;
import org.json.simple.*;
import views.html.*;
public class ApiController extends Controller {
public Result getUser(String userId) {
User user = User.findById(new ObjectId(userId));
JSONObject userG = new JSONObject();
//Some code to append data to userG before return
return ok(userG.toJSONString());
}
}
L'URL de l'itinéraire est défini comme suit:
GET /api/user/:id controllers.ApiController.getUser(id)
Option 1 pourrait être de vérifier le jeton d'autorisation dans la méthode getUser
et vérifier aussi pour d'autres informations d'identification, mais je veux restreindre l'accès avant même d'obtenir des appels méthode getUser
. Comme à l'avenir j'ajouterai plus d'appels de méthode à cette API REST. Je vais donc réutiliser la même autorisation pour ces futures API REST. J'ai trouvé authorization disponible dans Play Framework que je ne comprends pas. J'ai essayé de mettre en œuvre l'autorisation par l'extension de la classe Security.Authenticator
et les méthodes prépondérants getUserName
et onUnauthorized
comme ceci:
package controllers;
import models.Site;
import models.User;
import org.json.simple.JSONObject;
import play.mvc.Http.Context;
import play.mvc.Result;
import play.mvc.Security;
public class Secured extends Security.Authenticator {
@Override
public String getUsername(Context ctx) {
String auth_key = ctx.request().getHeader("X-Authorization");
Site site = Site.fineByAccessKey(auth_key);
if (site != null && auth_key.equals(site.access_key)) {
return auth_key;
} else {
return null;
}
}
@Override
public Result onUnauthorized(Context ctx) {
JSONObject errorAuth = new JSONObject();
errorAuth.put("status", "error");
errorAuth.put("msg", "You are not authorized to access the API");
return unauthorized(errorAuth.toJSONString());
}
}
J'ai joint en annexe l'annotation à la méthode getUser
avec @Security.Authenticated(Secured.class)
. Cela fonctionne correctement et renvoie une erreur non autorisée. Mais maintenant je ne suis pas sûr si c'est la manière préférée. Je pense que ce n'est pas la bonne façon de le faire comme le nom de l'override de la fonction getUsername
le suggère aussi. Je ne vérifie pas pour un nom d'utilisateur dans la session ou le cookie plutôt que le jeton présent dans l'en-tête de la demande.
Aussi je sais qu'il y a un module nommé Deadbolt
qui est utilisé pour l'autorisation mais je lis ses documents et je ne suis pas capable de l'intégrer. C'était une intégration relativement complexe pour un débutant comme moi. J'étais confus sur la façon de l'utiliser. J'ai pensé à utiliser l'autorisation du contrôleur SubjectPresent
mais je n'ai pas réussi à l'implémenter avec succès. En fin de compte, que suggérez-vous que devrais-je utiliser Security.Authenticator
comme j'ai implémenté? Ou suggérez-vous que je passe à ma première option qui vérifie l'autorisation à l'intérieur de la méthode getUser
? Ou Tout le monde peut me dire comment implémenter Deadbolt
dans mon scénario?
Juste pour tous ceux qui veulent savoir comment mettre en œuvre 'Security.Authenticated'. J'ai trouvé ce bon article suivant qui pourrait être une bonne aide: https://alexgaribay.com/2014/06/16/authentication-in-play-framework-using-java/ – Seeker