0

我有以下路线:

/projects/{projectName}

/projects/{projectName}/Wall/{wallName}

现在我想让所有的 GET 都被允许,但 PUT、POST、DELETE 应该只被项目成员允许,即该项目的用户成员。我有一个特殊的类,它给出了用户 ID 和项目名称,我可以获得用户成员资格的状态 - 类似于MyEnroler.getRole(userId, projectName)- 其中 userId 是请求标头的一部分,并且projectName是从 URI 中获取的。

我已经尝试了很多东西,但没有奏效。这是想法:

public class RoleMethodAuthorizer extends Authorizer {
    @Override
    protected boolean authorize(Request req, Response resp) {
        //If it's a get request then no need for further authorization. 
        if(req.getMethod().equals(Method.GET))
            return true;
        else
        {                               
            String authorEmail = req.getClientInfo().getUser().getIdentifier();
            String projectName = req.getAttributes().get("project").toString();

            Role userRole = MyEnroler.getRole(authorEmail, projectName);

            //forbid updates to resources if done by non-members of project
            if(userRole.equals(MyEnroler.NON_MEMBER))
                return false;
            //for everybody else, return true
            return true;
        }


    }

}

现在,在应用程序中创建入站根时,只需执行以下操作就完全失败了:

Router projectRouter = new Router(getContext());
RoleMethodAuthorizer rma = new RoleMethodAuthorizer();
//Guard declaration here. Then setNext Restlet
guard.setNext(projectRouter);
projectRouter.attach("/projects/{project}",rma);

Router wallRouter = new Router(getContext());
wallRouter.attach("/Wall/{wallName}", WallResource.class);

rma.setNext(wallRouter);

//return guard;

所以请求/projects/stackoverflow/Wall/restlet失败。永远找不到 URL。我猜是因为它试图将它与projectRouter. 好吧,我尝试了各种模式(MODE_BEST_MATCH or MODE_FIRST/NEXT_MATCH)无济于事。

似乎没有任何效果。从概念上讲,这应该有效。我只是拦截一个电话,只是对请求透明,但不知道内部情况如何。

我可以在警卫之后移动授权人,但我将无法访问request attribute-projectName我不希望自己解析 URL 来搜索 projectName,因为 URL 模式可能会改变并且会破坏功能 - 即需要 2变化而不是一个。

任何想法如何实现这一目标?

4

1 回答 1

2

我将使用标准的 RoleAuthorizer 类来提供允许的角色列表,以及您的自定义注册者可能会分成两部分,然后添加一个自定义过滤器类,该类执行类似的操作来调用您的注册者。

protected int beforeHandle(final Request request, final Response response) throws ResourceException {
    final String projectName = (String) request.getAttributes().get("projectName");
    // Check that a projectName is supplied, should not have got this far otherwise but lets check.
    if (projectName == null || projectName.isEmpty()) {
        throw new ResourceException(Status.CLIENT_ERROR_NOT_FOUND);
    }

    if (Method.GET.equals(request.getMethod())){
        new ReadEnroler(projectName).enrole(request.getClientInfo());
    }else{
        new MutateEnroler(projectName).enrole(request.getClientInfo());
    }

    return super.beforeHandle(request, response);
}

然后,在调用 enrole 时,登记者将在 clientInfo.getRoles() 集合中设置适当的值。

于 2012-09-24T10:37:22.557 回答