使用授权限制对 Play Framework 中方法的访问 - Java
Restricting Access to method in Play Framework with Authorization - Java
我无法理解 PlayFramework(2.5 版)中的授权概念。我的情况是我有一个 REST API 方法 getUser
,我想通过使用自定义请求 header 中名为 "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());
}
}
路由URL定义如下:
GET /api/user/:id controllers.ApiController.getUser(id)
选项 1 可能是检查方法中的授权令牌 getUser
并检查其他凭据,但我想在它获得调用之前限制访问 getUser
方法。将来我将向此 REST 添加更多方法调用 API。所以我也将对那些未来的 REST API 重新使用相同的授权。
我发现 Play Framework 中有 authorization 可用,但我无法理解。我试图通过扩展 class 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());
}
}
然后我用 @Security.Authenticated(Secured.class)
将注释附加到 getUser
方法。它工作正常并且 returns 未经授权的错误。但现在我不确定这是否是首选方式。我觉得这不是正确的方法,因为函数覆盖的名称 getUsername
也暗示了这一点。我不检查 session 或 cookie 中的任何用户名,而只检查请求的 header 中存在的令牌。
另外我知道有一个名为Deadbolt
which is used for authorization but I read its documents and I am not able to integrate it. It was relatively complex integration for a beginner like me. I was confused about how to use it. I thought about using SubjectPresent
controller authorization 的模块,但我仍然无法成功实现它。
最后你们有什么建议我应该使用 Security.Authenticator
我实现的方式吗?或者您是否建议我转到我的第一个选项,即在 getUser
方法中检查授权?或者任何人都可以告诉我如何在我的场景中实现 Deadbolt
?
您正在混合使用授权和身份验证。
这是一个很好的线程:Authentication versus Authorization
我喜欢这个答案:
Authentication = login + password (who you are)
Authorization = permissions (what you are allowed to do)
Authentication == Authorization(不包括匿名用户)如果您允许为您认识的所有用户做某事(即 已验证 用户)
Deadbolt 的主要目标是授权(已经通过身份验证的用户)。您的主要目标是 身份验证。
我建议你使用Pac4J, it Authentication library not only for Play, and it has versions as for Java as for Scala. There is a good sample project: https://github.com/pac4j/play-pac4j-java-demo
我自己在我的项目和任务中使用这个库
As in future i will be adding more method calls to this REST api. So i
will be reusing the same authorization to those future REST apis as
well.
我解决起来很简单,只需在'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"
}}
]
我无法理解 PlayFramework(2.5 版)中的授权概念。我的情况是我有一个 REST API 方法 getUser
,我想通过使用自定义请求 header 中名为 "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());
}
}
路由URL定义如下:
GET /api/user/:id controllers.ApiController.getUser(id)
选项 1 可能是检查方法中的授权令牌 getUser
并检查其他凭据,但我想在它获得调用之前限制访问 getUser
方法。将来我将向此 REST 添加更多方法调用 API。所以我也将对那些未来的 REST API 重新使用相同的授权。
我发现 Play Framework 中有 authorization 可用,但我无法理解。我试图通过扩展 class 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());
}
}
然后我用 @Security.Authenticated(Secured.class)
将注释附加到 getUser
方法。它工作正常并且 returns 未经授权的错误。但现在我不确定这是否是首选方式。我觉得这不是正确的方法,因为函数覆盖的名称 getUsername
也暗示了这一点。我不检查 session 或 cookie 中的任何用户名,而只检查请求的 header 中存在的令牌。
另外我知道有一个名为Deadbolt
which is used for authorization but I read its documents and I am not able to integrate it. It was relatively complex integration for a beginner like me. I was confused about how to use it. I thought about using SubjectPresent
controller authorization 的模块,但我仍然无法成功实现它。
最后你们有什么建议我应该使用 Security.Authenticator
我实现的方式吗?或者您是否建议我转到我的第一个选项,即在 getUser
方法中检查授权?或者任何人都可以告诉我如何在我的场景中实现 Deadbolt
?
您正在混合使用授权和身份验证。
这是一个很好的线程:Authentication versus Authorization
我喜欢这个答案:
Authentication = login + password (who you are)
Authorization = permissions (what you are allowed to do)
Authentication == Authorization(不包括匿名用户)如果您允许为您认识的所有用户做某事(即 已验证 用户)
Deadbolt 的主要目标是授权(已经通过身份验证的用户)。您的主要目标是 身份验证。
我建议你使用Pac4J, it Authentication library not only for Play, and it has versions as for Java as for Scala. There is a good sample project: https://github.com/pac4j/play-pac4j-java-demo
我自己在我的项目和任务中使用这个库
As in future i will be adding more method calls to this REST api. So i will be reusing the same authorization to those future REST apis as well.
我解决起来很简单,只需在'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"
}}
]