我按照Jersey教程为我的应用程序实现了完全自定义的SecurityContext
。我创建了一个自定义ContainerRequestFilter
来设置SecurityContext
,如下所示:
package com.my.security;
@Provider
@Priority(Priorities.AUTHORIZATION)
public class SecurityRequestFilter implements ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext requestContext) {
requestContext.setSecurityContext(new MySecurityContext(requestContext));
}
public static final class MySecurityContext implements SecurityContext {
private String token;
public MySecurityContext(ContainerRequestContext requestContext) {
token = requestContext.getHeaderString("token");
}
@Override
public boolean isUserInRole(String role) {
return role.equals("admin") && token.equals("token-for-admin");
}
// other methods omitted
}
}
isUserInRole
方法中的逻辑是无关紧要的,它只是一个嘲弄点。
我的端点看起来像:
package com.my.rest;
@PermitAll
@Path("/people")
public class PeopleRestService {
@RolesAllowed({"admin"})
@Path("/{email}")
@DELETE
public Response deletePerson(@PathParam("email") final String email) {
peopleService.removePerson(email);
return Response.ok().build();
}
}
现在我创建了一个测试(使用JerseyTest
)配置了两个类所在的包:
@Override
protected Application configure() {
return new ResourceConfig().packages("com.my.rest", "com.my.security");
}
如果我在测试中执行以下操作:
Response response = target("people/my@email.com")
.request().header("token", "token-for-admin").delete();
Assert.assertEquals(200, response.getStatus());
一切正常。
但是,如果我执行以下内容:
Response response = target("people/my@email.com").request().delete();
Assert.assertEquals(403, response.getStatus());
我希望403错误代码,因为我没有设置身份验证令牌。但是,我得到一个500错误代码和一个Grizzly(用于测试的容器)HTML响应,字符串“请求失败。”。
如果我在@Provider
类上注释掉SecurityRequestFilter
注释或从测试配置中删除包com.my.security
,则Jersey会使用提供的容器SecurityContext
并正确返回403代替。
为什么会这样?泽西岛不应该返回带有自定义SecurityContext
的403吗?我错过了什么?
答案 0 :(得分:1)
isUserInRole
方法中的逻辑完全相关!我在那里有一个NPE,我没有看到并导致了500.