2012-09-14 40 views
0

我有以下途徑:如何在使用Restlet的「URL中間」添加過濾器?

/projects/{projectName}

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

現在我想有所有得到允許,但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)無濟於事。

似乎沒有任何工作。從概念上講,這應該工作。我只是攔截一個電話,只是對請求透明,但不知道內部是如何工作的。

我可以在授權者後面移動授權者,但我無法訪問projectNamerequest attribute - 我不希望自己解析URL來搜索projectName,因爲URL模式可能會更改並會中斷功能 - 即需要2次更改而不是1次。

任何想法如何實現這一目標?

回答

2

我會使用標準的RoleAuthorizer類來提供允許角色的列表,以及您的自定義註冊器可能分成兩個,然後我會添加一個自定義的Filter類,這樣做可以調用您的Enrolers。然後

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); 
} 

的enrolers會設置適當的值在clientInfo.getRoles()系列時enrole被調用。

相關問題