我已经实现了执行基于JWT的身份验证的ContainerRequestFilter
:
@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());
}
}
}
如您所见,如果身份验证成功,我将更新请求的
SecurityContext
,并将其设置为我自己的自定义实现(JwtSecurityContext
)的实例。此实现添加了额外的身份验证和授权数据,我希望稍后在后续的过滤器和资源方法中访问这些数据。我还实现了一个
AuthorizationFilter
,它在AuthenticationFilter
之后立即被调用。在这里,我可以正常访问更新的JwtSecurityContext
。但是,当我尝试将
JwtSecurityContext
注入(inject)资源(方法)时遇到问题。我目前正在使用Jersey和I've read the following in its documentation:
我尝试将
JwtSecurityContext
注入(inject)资源方法中,如下所示:@Path("/somepath")
public class SomeResource {
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<SomeItem> getItems(@Context SecurityContext securityContext) {
// securityContext is of type 'SecurityContextInjectee'
}
}
如注释所示,
securityContext
变量的运行时类型变为SecurityContextInjectee
。通过调试,我发现它包装了ContainerRequest
,而包装了JwtSecurityContext
。但是,没有 setter/getter ,并且我不想使用反射来深入研究此对象层次结构,因此我不知道如何控制JwtSecurityContext
。我尝试将
@Context SecurityContext securityContext
更改为@Context JwtSecurityContext jwtSecurityContext
,但是如果执行此操作,则该变量将变为null
。我也尝试过场注入(inject),但是行为方式相同。我要走错路了吗?我应该在资源方法中不访问我的自定义
SecurityContext
吗?一种选择是将我的所有数据包装在从Principal
中的getUserPrincipal
返回的JwtSecurityContext
实现中。我想代理(SecurityContextInjectee
)会将调用转发到其底层JwtSecurityContext
并因此返回我的Principal
,但是我不确定,最终我更喜欢使用JwtSecurityContext
而不是将这些值包装在Principal
实现中。 最佳答案
您可以注入(inject)ContainerRequestContext
(如this post中所述),然后从那里获取SecurityContext
。
public List<SomeItem> getItems(@Context ContainerRequestContext context) {
JwtSecurityContext sec = (JwtSecurityContext)context.getSecurityContext();
}