使用Jersey和会话管理进行REST授权

时间:2015-10-01 15:41:54

标签: java rest session jersey

我有一个带有Jersey的RESTful Java后端。问题是我不知道如何实现方法的授权。我的意思是如何检查用户是否有权使用我的REST API的给定方法?

当然,如果我寻找“泽西授权”,我会有@RolesAllowed,@ PermitAll和@DenyAll这些不错的注释。但是,这些注释对服务器领域起作用,与服务器的用户无关,与您存储在数据库中的应用程序用户无关。

因此,为了授权,我该怎么办?我定义了一个过滤器,用于检查用户是否在我的应用程序中登录?我必须将过滤器应用于需要身份验证的REST端点吗?

这似乎有点像“过去”,这就是为什么我要求更好的方法来做到这一点。

2 个答案:

答案 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