Java 允许使用角色的Jersey声明性链接权限
我想将Jersey的声明性链接功能与其角色允许功能结合起来 我能够成功地将链接注入到响应中,但这种注入并不关注该端点的RolesAllowed注释 例如,想象两个用户。称他们为管理员和用户。两者都可以访问GET资源,但只有管理员可以访问DELETE 如果资源方法受@RolesAllowed保护,那么我希望没有该角色的用户不会注入该端点。情况似乎并非如此 我遵循了我发现的例子 下面是我正在进行的项目的简化版本,以便于说明 对于admin,我希望使用以下jsonJava 允许使用角色的Jersey声明性链接权限,java,rest,jersey,jax-rs,hateoas,Java,Rest,Jersey,Jax Rs,Hateoas,我想将Jersey的声明性链接功能与其角色允许功能结合起来 我能够成功地将链接注入到响应中,但这种注入并不关注该端点的RolesAllowed注释 例如,想象两个用户。称他们为管理员和用户。两者都可以访问GET资源,但只有管理员可以访问DELETE 如果资源方法受@RolesAllowed保护,那么我希望没有该角色的用户不会注入该端点。情况似乎并非如此 我遵循了我发现的例子 下面是我正在进行的项目的简化版本,以便于说明 对于admin,我希望使用以下json { "id" : 1
{
"id" : 1
"value" : "someValue",
"links" : [
{
"href": "http://localhost/context/model/1",
"rel": "self",
"type": "GET"
},
{
"href": "http://localhost/context/model/1",
"rel": "delete",
"type": "DELETE"
},
},
}
这正是我得到的。不幸的是,对于没有访问该端点所需的正确角色的用户,我也得到了此响应。用户仍将获得指向删除端点的链接,但由于角色被允许,该用户将收到403
型号
public class Model {
private int id;
private String value;
//constructor/getters/setters
模型表示法
public class ModelRep {
@XmlPath(".") //Allows me to flatten json so that links and document are at the same level
private Model model;
@InjectLinks({
@InjectLink(
rel = "self",
type = "GET",
resource = ModelResource.class,
method = "getModel",
bindings = @Binding(name = "id", value = "${instance.id}"),
style = Style.ABSOLUTE
),
@InjectLink(
rel = "delete",
type = "DELETE",
resource = ModelResource.class,
method = "deleteModel",
bindings = @Binding(name = "id", value = "${instance.id}"),
style = Style.ABSOLUTE
)
})
@XmlJavaTypeAdapter(LinkAdapter.class)
private List<Link> links;
//constructor/getters/setters
公共类ModelRep{
@XmlPath(“.”//允许我展平json,以便链接和文档处于同一级别
私有模型;
@注入链接({
@注入链接(
rel=“self”,
type=“GET”,
resource=ModelResource.class,
method=“getModel”,
bindings=@Binding(name=“id”,value=“${instance.id}”),
style=style.ABSOLUTE
),
@注入链接(
rel=“删除”,
type=“删除”,
resource=ModelResource.class,
方法=“删除模型”,
bindings=@Binding(name=“id”,value=“${instance.id}”),
style=style.ABSOLUTE
)
})
@XmlJavaTypeAdapter(LinkAdapter.class)
私人列表链接;
//构造函数/获取器/设置器
模型资源
@Path("/model")
@Produces(MediaType.APPLICATION_JSON)
public class ModelResource {
@GET
@Path("/{id}")
public Response getModel(@PathParam("id") int id) {
Model m = dao.get(id);
ModelRep mr = new modelRep(m);
GenericEntity<ModelRep> ent = new GenericEntity<ModelRep>(mr) {};
return Response.status(Status.OK).entity(ent);
}
@DELETE
@Path("/{id}")
@RolesAllowed(Roles.ADMIN)
public Response deleteModel(@PathParam("id") int id) {
dao.delete(id);
return Response.status(Status.NO_CONTENT);
}
@Path(“/model”)
@产生(MediaType.APPLICATION_JSON)
公共类模型资源{
@得到
@路径(“/{id}”)
公共响应getModel(@PathParam(“id”)int-id){
模型m=dao.get(id);
ModelRep mr=新ModelRep(m);
GenericEntity ent=新的GenericEntity(mr){};
返回响应.status(status.OK).entity(ent);
}
@删除
@路径(“/{id}”)
@允许角色(Roles.ADMIN)
公共响应deleteModel(@PathParam(“id”)int-id){
删除(id);
返回响应。状态(状态。无内容);
}
问题
是否有某种方法可以基于RolesAllowed实现条件声明性链接
我知道InjectLink注释存在一个条件子句,但该子句允许的值是实例(ModelRep)、实体(我认为是响应对象?)和资源(ModelResource)
我不知道如何使用其中任何一个来检查权限
非常感谢您的建议,因此我最终找到了一个解决方案,虽然有点粗糙,但效果相当不错 每个资源扩展一个基本资源类别
@Path("/model")
@Produces(MediaType.APPLICATION_JSON)
public class ModelResource extends BaseResource {
BaseResource定义一个公共方法,该方法返回当前资源的特定方法是否受RoleAllowed注释的限制
public abstract class BaseResource {
@Context
private SecurityContext security;
public boolean isMethodRoleProtected(String sMethod) {
Method[] methods = this.getClass().getDeclaredMethods();
for (Method m : methods) {
if (m.getName().equalsIgnoreCase(sMethod)) {
Annotation[] annotations = m.getAnnotations();
for (Annotation a : annotations) {
if (a instanceof RolesAllowed) {
String[] roles = ((RolesAllowed) a).value;
return userHasRole(roles);
}
}
}
}
return false;
}
protected boolean userHasRole(String... roles) {
for (String role : roles) {
if (security.isUserInRole(role)) {
return true;
}
}
return false;
}
}
最后,InjectLink注释如下所示
@InjectLink(
rel = "self",
type = "GET",
resource = SomeResource.class,
method = "someMethod",
bindings = @Binding(name = "id", value = "${instance.id}"),
style = Style.ABSOLUTE,
condition = "${resource.isMethodRoleProtected(someMethod)}"
),
“resource”是扩展BaseResource的当前终结点类的实例。因此,仅当当前用户的角色存在于该方法的RolesAllowed批注中时,才会注入此链接
此解决方案需要实现SecurityContext
如果其他人有更好/更干净的解决方案或改进我找到的解决方案的方法,我仍然很乐意听到,并将相应地调整接受的答案。干杯