See*_*ker 2 java authentication playframework deadbolt-2 playframework-2.5
我无法理解 PlayFramework(版本 2.5)中的授权概念。我的情况是我有一个 REST API 方法getUser,我想通过使用名为 的自定义请求标头中的令牌执行授权来限制其访问"X-Authorization"。现在我的控制器代码如下所示:
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());
}
}
Run Code Online (Sandbox Code Playgroud)
路由 URL 定义如下:
GET /api/user/:id controllers.ApiController.getUser(id)
Run Code Online (Sandbox Code Playgroud)
选项 1可能是检查方法内的授权令牌getUser,并检查其他凭据,但我想在调用getUser方法之前限制访问。将来我将向此 REST API 添加更多方法调用。因此,我也将对未来的 REST API 重复使用相同的授权。
我发现 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());
}
}
Run Code Online (Sandbox Code Playgroud)
然后我将注释附加到该getUser方法中@Security.Authenticated(Secured.class)。它工作正常并返回未经授权的错误。但现在我不确定这是否是首选方式。我觉得这不是正确的方法,因为函数重写的名称getUsername也表明了这一点。我不检查会话或 cookie 中的任何用户名,而只检查请求标头中存在的令牌。
我还知道有一个名为Deadbolt用于授权的模块,但我阅读了它的文档,但无法集成它。对于像我这样的初学者来说,这是相对复杂的集成。我对如何使用它感到困惑。我考虑过使用SubjectPresent控制器授权,但仍然无法成功实现。
最后,你们建议我应该使用Security.Authenticator我实施的方式吗?或者您建议我转到第一个选项,即检查getUser方法内部的授权?或者任何人都可以告诉我如何Deadbolt在我的场景中实现?
您正在混合授权和身份验证。
这是一个很好的主题: 身份验证与授权
我喜欢这个答案:
身份验证= 登录名 + 密码(您是谁)
授权=权限(允许你做什么)
身份验证==授权(不包括匿名用户)如果您允许为您认识的所有用户(即经过身份验证的用户)执行某些操作
Deadbolt的主要目标是授权(已经经过身份验证的用户)。您的主要目标是Authentication。
我建议你使用Pac4J,它的身份验证库不仅适用于 Play,而且它还有适用于 Java 和 Scala 的版本。有一个很好的示例项目:https ://github.com/pac4j/play-pac4j-java-demo
我自己在我的项目和任务中使用这个库
将来我将向此 REST api 添加更多方法调用。因此,我也将对未来的 REST api 重复使用相同的授权。
我解决的方法很简单,只需在“application.conf”中添加配置即可:
pac4j.security {
rules = [
{"/admin/.*" = {
authorizers = "ADMIN"
clients = "FormClient"
}}
]
}
Run Code Online (Sandbox Code Playgroud)
只是不要忘记添加安全过滤器。此功能存在于示例项目中,因此只需克隆并尝试即可。
官方页面的另一个例子:
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"
}}
]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2794 次 |
| 最近记录: |