Jersey 和会话管理的 REST 授权
REST authorization with Jersey and session management
我有一个 RESTful Java 后端与 Jersey。问题是我不知道如何为这些方法实现授权。我的意思是如何检查用户是否有权使用我的 REST API?
的给定方法
当然,如果我查找 "Jersey authorization",我会得到那些不错的注释,例如 @RolesAllowed、@PermitAll 和 @DenyAll。但是,这些注释针对服务器领域,与服务器用户一起使用,与您存储在数据库中的应用程序用户无关。
那么为了授权,我该怎么办?我定义了一个过滤器来检查用户是否在我的应用程序中登录?我必须将过滤器应用于需要身份验证的 REST 端点吗?
这似乎有点 "like the old days",这就是为什么我问更好的方法。
So for the sake authorization, what should I do? I define a filter that checks if the user is logged in my application? I have to apply the filter to the REST endpoints that need authentication?
嗯...我猜你不会开心,但这基本上就是你需要做的。
一些代码建议;
public class Application extends ResourceConfig {
public Application() {
super();
register(RolesAllowedDynamicFeature.class); // this is for @RolesAllowed
register(AuthenticationRequestFilter.class); // your auth filter
}
}
然后,对于基本身份验证,我这样做:
@PreMatching
public class AuthenticationRequestFilter implements ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext request) throws IOException {
String authorization = request.getHeaderString("Authorization"); // get BasicAuth header
if (StringUtils.isNotEmpty(authorization) && StringUtils.startsWith(authorization, "Basic")) {
... do the password check... you have base64 encrypted string here
request.setSecurityContext(new SecurityContext(){
...implementation...
});
}}}
但是,大部分工作需要您自己完成。
编辑
要使 @RolesAllowed 正常工作,您需要在身份验证过滤器中设置 SecurityContext
。如果用户通过身份验证,则需要设置适当的上下文(就像我在上面的代码片段中所做的那样)。
这个上下文实际上允许您使用它的方法执行您喜欢的任何逻辑来检查角色、用户名等;例如我的实现是:
public class AuthorizedContext implements SecurityContext {
private final InternalUserBean user;
public AuthorizedContext(InternalUserBean user) {
this.user = user;
}
@Override
public Principal getUserPrincipal() {
return () -> getUser().getUsername();
}
@Override
public boolean isUserInRole(String s) {
// this does the proper check for @RolesAllowed annotation.
return StringUtils.equals(s, getUser().getRole());
}
@Override
public boolean isSecure() {
return false;
}
@Override
public String getAuthenticationScheme() {
return "YourRealmName";
}
public InternalUserBean getUser() {
return user;
}
}
看了很多之后,我在这里找到了一个非常好的(很酷的解决方案):
Jersey Request Filter only on certain URI
因此,为了仅检查使用您的自定义注释注释的那些方法的授权(您的授权 ContainerRequestFilter
仅过滤 REST API 的注释方法)。我把它命名为@AuthorizationRequired
我有一个 RESTful Java 后端与 Jersey。问题是我不知道如何为这些方法实现授权。我的意思是如何检查用户是否有权使用我的 REST API?
的给定方法当然,如果我查找 "Jersey authorization",我会得到那些不错的注释,例如 @RolesAllowed、@PermitAll 和 @DenyAll。但是,这些注释针对服务器领域,与服务器用户一起使用,与您存储在数据库中的应用程序用户无关。
那么为了授权,我该怎么办?我定义了一个过滤器来检查用户是否在我的应用程序中登录?我必须将过滤器应用于需要身份验证的 REST 端点吗?
这似乎有点 "like the old days",这就是为什么我问更好的方法。
So for the sake authorization, what should I do? I define a filter that checks if the user is logged in my application? I have to apply the filter to the REST endpoints that need authentication?
嗯...我猜你不会开心,但这基本上就是你需要做的。
一些代码建议;
public class Application extends ResourceConfig {
public Application() {
super();
register(RolesAllowedDynamicFeature.class); // this is for @RolesAllowed
register(AuthenticationRequestFilter.class); // your auth filter
}
}
然后,对于基本身份验证,我这样做:
@PreMatching
public class AuthenticationRequestFilter implements ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext request) throws IOException {
String authorization = request.getHeaderString("Authorization"); // get BasicAuth header
if (StringUtils.isNotEmpty(authorization) && StringUtils.startsWith(authorization, "Basic")) {
... do the password check... you have base64 encrypted string here
request.setSecurityContext(new SecurityContext(){
...implementation...
});
}}}
但是,大部分工作需要您自己完成。
编辑
要使 @RolesAllowed 正常工作,您需要在身份验证过滤器中设置 SecurityContext
。如果用户通过身份验证,则需要设置适当的上下文(就像我在上面的代码片段中所做的那样)。
这个上下文实际上允许您使用它的方法执行您喜欢的任何逻辑来检查角色、用户名等;例如我的实现是:
public class AuthorizedContext implements SecurityContext {
private final InternalUserBean user;
public AuthorizedContext(InternalUserBean user) {
this.user = user;
}
@Override
public Principal getUserPrincipal() {
return () -> getUser().getUsername();
}
@Override
public boolean isUserInRole(String s) {
// this does the proper check for @RolesAllowed annotation.
return StringUtils.equals(s, getUser().getRole());
}
@Override
public boolean isSecure() {
return false;
}
@Override
public String getAuthenticationScheme() {
return "YourRealmName";
}
public InternalUserBean getUser() {
return user;
}
}
看了很多之后,我在这里找到了一个非常好的(很酷的解决方案):
Jersey Request Filter only on certain URI
因此,为了仅检查使用您的自定义注释注释的那些方法的授权(您的授权 ContainerRequestFilter
仅过滤 REST API 的注释方法)。我把它命名为@AuthorizationRequired