Jan*_*ken 3 java authentication authorization jax-rs jersey
我已经实现了一个ContainerRequestFilter执行基于JWT的身份验证:
@Provider
@Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter {
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
AuthenticationResult authResult = ...
if (authResult.isSuccessful()) {
// Client successfully authenticated.
// Now update the security context to be the augmented security context that contains information read from the JWT.
requestContext.setSecurityContext(new JwtSecurityContect(...));
} else {
// Client provided no or an invalid authentication token.
// Deny request by sending a 401 response.
requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).build());
}
}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我更新了SecurityContext请求,JwtSecurityContext如果身份验证成功,则将其设置为我自己的自定义实现()的实例.此实现添加了额外的身份验证和授权数据,我希望稍后在后续过滤器和我的资源方法中访问这些数据.
我还实现了一个AuthorizationFilter在之后立即调用的AuthenticationFilter.在这里,我可以访问更新JwtSecurityContext就好了.
但是,当我尝试将JwtSecurityContext资源注入资源(方法)时,我遇到了问题.
我目前正在使用Jersey,我在其文档中阅读了以下内容:
在
SecurityContext可以从直接检索ContainerRequestContext经由getSecurityContext()方法.您还可以SecurityContext使用该setSecurityContext(SecurityContext)方法将请求上下文中的默认值替换为自定义上下文中的默认值.如果在您的设置中设置自定义SecurityContext实例ContainerRequestFilter,则此安全上下文实例将用于注入JAX-RS资源类字段.这样,您就可以实现自定义身份验证筛选器,可以设置自己的身份验证筛选器SecurityContext.要确保提前执行自定义身份验证请求筛选器,请使用常量将筛选器优先级设置为AUTHENTICATIONPriorities.早期执行身份验证筛选器将确保所有其他筛选器,资源,资源方法和子资源定位器将与您的自定义SecurityContext实例一起执行 .
我尝试将这样注入JwtSecurityContext资源方法:
@Path("/somepath")
public class SomeResource {
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<SomeItem> getItems(@Context SecurityContext securityContext) {
// securityContext is of type 'SecurityContextInjectee'
}
}
Run Code Online (Sandbox Code Playgroud)
正如注释所示,securityContext变量的运行时类型变为SecurityContextInjectee.从调试开始,我发现它包裹了一个ContainerRequest反过来包裹我的JwtSecurityContext.但是,没有getter,我不想使用反射来深入挖掘这个对象层次结构,所以我不知道如何抓住我的JwtSecurityContext.
我试图改变@Context SecurityContext securityContext到@Context JwtSecurityContext jwtSecurityContext,但如果我这样做,变变null.我也尝试过野外注射,但这种行为方式相同.
我走错了路吗?我不应该SecurityContext在我的资源方法中访问我的自定义吗?一种替代方法是将我的所有数据包装在Principal我从getUserPrincipal我的实现中返回的实现中JwtSecurityContext.我想proxy(SecurityContextInjectee)会将调用转发给它的底层JwtSecurityContext因此返回我的Principal,但我不确定,最后我宁愿使用my JwtSecurityContext而不是在Principal实现中包装这些值.
您可以注入ContainerRequestContext(如中提到的这篇文章),只是得到了SecurityContext从那里.
public List<SomeItem> getItems(@Context ContainerRequestContext context) {
JwtSecurityContext sec = (JwtSecurityContext)context.getSecurityContext();
}
Run Code Online (Sandbox Code Playgroud)