我正在使用Jersey(2.28)创建一个RESTful服务,并使用Apache Shiro进行权限处理。因此,我使用了内置HttpMethodPermissionFilter
来创建诸如resource:read
或resource:write
之类的权限。现在,我遇到的问题是,可能只允许用户读取或写入特定资源,并且我需要诸如resource:write:<id>
或resource:write:<name>
之类的东西,或者像标识符一样的东西。
我考虑过扩展过滤器,但是到那时-即使我可以访问正文或url-我也不知道数据的样子。
我想到的解决方案:
始终在URL中传递查询参数,例如/api/resource?id=xxx
,如果给定参数,则将该参数应用于权限字符串。但是无法判断是否需要参数resource:read
和resource:read:<id>
是否都存在。过滤器可能为给定的URL创建了错误的权限。我可以将过滤器仅应用到我知道一定是这种情况的网址,但似乎有点不可靠且容易出错。
删除过滤器,并在请求的方法内询问权限。
@GET
@Path("/resource/{id}")
public Response getResource(@PathParam("id") String id) {
if(AuthorizationHandler.hasPermission("resource:read:" + id) {
return Response.status(Status.OK).entity("Resource GET works").build();
}
// return 403 or handle exception or ...
}
有点像,但是这会使我在每种方法中都进行异常处理,这似乎也不太可取。也许我可以使用ExceptionMapper
来处理响应……没有尝试过。
也许其他人对如何有效地解决这个问题有另一个想法,或者将我指向一个已经存在的解决方案?我更喜欢使用@RequiresPermissions("resource:read")
注解(或自定义注解),但也可以在shiro.ini文件/api/resource/** = noSessionCreation, jwtf, rest[resource]
中定义urls /过滤器,或者如果建议这样做,我可以使用解决方案2。