2

У меня возникли проблемы с пониманием идеи авторизации в PlayFramework (версия 2.5). Моя ситуация заключается в том, что у меня есть метод REST API getUser, и я хочу ограничить его доступ, выполнив авторизацию с помощью токена, который входит в заголовок настраиваемого запроса с именем "X-Authorization". Теперь мой контроллер код выглядит следующим образом:Ограничение доступа к методу в Play Framework с авторизацией - 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()); 
    } 
} 

URL-адрес маршрута определяется следующим образом:

GET /api/user/:id controllers.ApiController.getUser(id) 

Вариант 1 может проверить маркер авторизации внутри метода getUser, а также проверить другие учетные данные, но я хочу ограничить доступ до того, как он получит вызовы getUser. Как и в будущем, я буду добавлять дополнительные вызовы методов для этого REST API. Поэтому я буду повторно использовать то же разрешение для этих будущих API REST.

Я нашел, что есть authorization, доступный в Play Framework, который я не могу понять. Я пытался реализовать Авторизация путем расширения класса Security.Authenticator и Переопределение методов getUserName и onUnauthorized вроде этого:

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()); 
    } 
} 

Тогда я приложил аннотацию к методу getUser с @Security.Authenticated(Secured.class). Он отлично работает и возвращает несанкционированную ошибку. Но теперь я не уверен, что это предпочтительный способ. Я считаю, что это неправильный способ сделать это, так как это говорит о переопределении функции getUsername. Я не проверяю ни одно имя пользователя в сеансе или cookie, а только токен, присутствующий в заголовке запроса.

Также я знаю, что есть модуль с именем Deadbolt, который используется для авторизации, но я читаю его документы, и я не могу его интегрировать. Это была относительно сложная интеграция для новичка, подобного мне. Я был смущен тем, как его использовать. Я думал об использовании авторизации контроллера SubjectPresent, но все же я не смог его успешно реализовать.

В конце концов, что вы, ребята, предлагаете мне использовать Security.Authenticator так, как я это сделал? Или вы предлагаете мне перейти к моему первому варианту, который проверяет авторизацию внутри метода getUser? Или кто-нибудь может сказать мне, как реализовать Deadbolt в моем сценарии?

+0

Только для тех, кто хочет знать, как реализовать 'Security.Authenticated'. я нашел эту следующую приятную статью, которая может быть хорошей помощью: https://alexgaribay.com/2014/06/16/authentication-in-play-framework-using-java/ – Seeker

ответ

2

Вы смешиваете авторизацию и аутентификацию.

Вот хороший поток: Authentication versus Authorization

Мне нравится этот ответ:

Authentication = логин + пароль (который вы)

авторизации = разрешений (что вам разрешается делать)

Аутентификация == Авторизация (за исключением анонимного пользователя), если вы разрешаете делать что-либо для всех пользователей, которых вы знаете (т.Аутентифицированные пользователей)

Основной целью Deadbolt является Авторизация (уже Аутентифицированные пользователей). Ваша основная цель - Аутентификация.

Я бы посоветовал вам использовать Pac4J, он Authentication библиотеки не только для игры, и имеет версии как для Java, как для Scala. Существует хороший пример проект: https://github.com/pac4j/play-pac4j-java-demo

Я использую эту библиотеку сам в своих проектах и ​​задача

Как и в будущем я буду добавлять больше вызовов методы к этому REST API. Таким образом, i будет повторно использовать то же разрешение для этих будущих REST apis, как и .

решаю так же просто, как просто добавить конфигурацию в «application.conf`:

pac4j.security { 
    rules = [ 
    {"/admin/.*" = { 
     authorizers = "ADMIN" 
     clients = "FormClient" 
    }} 
    ] 
} 

Только не забудьте добавить фильтр безопасности. Эта функция присутствует в примере проекта, поэтому просто клонируйте и попробуйте.

Другой пример формы the official page:

pac4j.security.rules = [ 
    # Admin pages need a special authorizer and do not support login via Twitter. 
    {"/admin/.*" = { 
    authorizers = "admin" 
    clients = "FormClient" 
    }} 
    # Rules for the REST services. These don't specify a client and will return 401 
    # when not authenticated. 
    {"/restservices/.*" = { 
    authorizers = "_authenticated_" 
    }} 
    # The login page needs to be publicly accessible. 
    {"/login.html" = { 
    authorizers = "_anonymous_" 
    }} 
    # 'Catch all' rule to make sure the whole application stays secure. 
    {".*" = { 
    authorizers = "_authenticated_" 
    clients = "FormClient,TwitterClient" 
    }} 
] 
+0

Спасибо за разъяснение об аутентификации и авторизации. Я загляну в модуль pac4j. – Seeker

 Смежные вопросы

  • Нет связанных вопросов^_^