我有一个带有Jersey的RESTful Java后端。问题是我不知道如何实现方法的授权。我的意思是如何检查用户是否有权使用我的REST API的给定方法?
当然,如果我寻找“泽西授权”,我会有@RolesAllowed,@ PermitAll和@DenyAll这些不错的注释。但是,这些注释对服务器领域起作用,与服务器的用户无关,与您存储在数据库中的应用程序用户无关。
因此,为了授权,我该怎么办?我定义了一个过滤器,用于检查用户是否在我的应用程序中登录?我必须将过滤器应用于需要身份验证的REST端点吗?
这似乎有点像“过去”,这就是为什么我要求更好的方法来做到这一点。
答案 0 :(得分:4)
因此,为了授权,我该怎么办?我定义了一个过滤器,用于检查用户是否已登录我的应用程序?我必须将过滤器应用于需要身份验证的REST端点吗?
嗯......我想你会不高兴,但基本上你需要这样做。
一些代码建议;
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
。如果用户通过身份验证,则需要设置正确的上下文(就像我在上面的代码snipet中所做的那样)。
这个上下文实际上允许你做任何你喜欢的逻辑来检查角色,用户名等及其方法;例如我的实现是:
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;
}
}
答案 1 :(得分:1)
阅读A LOT后,我发现了一个非常好的(很酷的解决方案):
Jersey Request Filter only on certain URI
因此,为了仅检查使用自定义注释注释的方法的授权(您的授权<form action="contact.php" method="post">
<input type="text" class="textbox" value=" Your Name" onfocus="this.value = '';" onblur="if (this.value == '') {this.value = 'Your Name';}">
<input type="text" class="textbox" value="Your E-Mail" onfocus="this.value = '';" onblur="if (this.value == '') {this.value = 'Your E-Mail';}">
<div class="clear"> </div>
<div>
<textarea value="Message:" onfocus="this.value = '';" onblur="if (this.value == '') {this.value = 'Your Message ';}">Your Message</textarea>
</div>
<div class="submit">
<input type="submit" value="SEND " />
</div>
</form>
仅过滤REST API的注释方法)。我把它命名为ContainerRequestFilter