JAX-RS:自定义SecurityContext注入资源方法时具有意外类型 [英] JAX-RS: Custom SecurityContext has unexpected type when injected into resource method
问题描述
我已经实现了执行基于JWT的身份验证的ContainerRequestFilter
:
I have implemented a ContainerRequestFilter
that performs JWT-based authentication:
@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
)的实例.此实现添加了额外的身份验证和授权数据,我希望稍后在后续的过滤器和资源方法中访问这些数据.
As you can see, I update the SecurityContext
of the request, setting it to be an instance of my own custom implementation (JwtSecurityContext
) if authentication succeeds. This implementation adds extra authentication and authorization data, which I would like to later access in my subsequent filter(s) and my resource methods.
我还实现了AuthorizationFilter
,该AuthorizationFilter
在AuthenticationFilter
之后立即被调用.在这里,我可以正常访问更新的JwtSecurityContext
.
I have also implemented an AuthorizationFilter
that is invoked immediately after the AuthenticationFilter
. Here, I can access the updated JwtSecurityContext
just fine.
但是,当我尝试将JwtSecurityContext
注入资源(方法)时遇到了问题.
However, I am having problems when I try to inject the JwtSecurityContext
into a resource (method).
我当前正在使用Jersey,并且我已经在其文档中阅读了以下内容:
I am currently using Jersey, and I've read the following in its documentation:
SecurityContext
可以直接从ContainerRequestContext
通过getSecurityContext()
方法.你也可以 用自定义替换请求上下文中的默认SecurityContext
一种使用setSecurityContext(SecurityContext)
方法.如果您设置了 您的ContainerRequestFilter
中的自定义SecurityContext
实例, 安全上下文实例将用于注入JAX-RS 资源类字段.这样您就可以实现自定义 身份验证筛选器,可以将您自己的SecurityContext
设置为 用过的.为了确保尽早执行您的自定义身份验证 请求过滤器,使用以下命令将过滤器优先级设置为AUTHENTICATIONPriorities
中的常量.尽早执行身份验证 过滤器将确保所有其他过滤器,资源,资源方法 和子资源定位器将按照您的自定义执行SecurityContext
实例.
The
SecurityContext
can be directly retrieved fromContainerRequestContext
viagetSecurityContext()
method. You can also replace the defaultSecurityContext
in a request context with a custom one using thesetSecurityContext(SecurityContext)
method. If you set a customSecurityContext
instance in yourContainerRequestFilter
, this security context instance will be used for injection into JAX-RS resource class fields. This way you can implement a custom authentication filter that may setup your ownSecurityContext
to be used. To ensure the early execution of your custom authentication request filter, set the filter priority to AUTHENTICATION using constants fromPriorities
. An early execution of you authentication filter will ensure that all other filters, resources, resource methods and sub-resource locators will execute with your customSecurityContext
instance.
我尝试将JwtSecurityContext
注入资源方法,如下所示:
I try to inject the JwtSecurityContext
into a resource method like so:
@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
.但是,没有吸气剂,并且我不想使用反射来深入研究此对象层次结构,因此我不知道如何控制我的JwtSecurityContext
.
As the comment indicates, the runtime type of the securityContext
variable becomes SecurityContextInjectee
. From debugging, I've observed that this wraps a ContainerRequest
which in turn wraps my JwtSecurityContext
. However, there are no getters, and I do not want to use reflection to drill down this object hierarchy, so I don't know how to get a hold on my JwtSecurityContext
.
我尝试将@Context SecurityContext securityContext
更改为@Context JwtSecurityContext jwtSecurityContext
,但是如果执行此操作,变量将变为null
.我还尝试了场注入,但是行为方式相同.
I have tried changing @Context SecurityContext securityContext
to @Context JwtSecurityContext jwtSecurityContext
, but if I do this, the variable becomes null
. I have also tried field injection, but this behaves the same way.
我要走错路了吗?我不应该在资源方法中访问自定义SecurityContext
吗?一种选择是将我的所有数据包装在JwtSecurityContext
中从getUserPrincipal
返回的Principal
实现中.我想代理(SecurityContextInjectee
)会将呼叫转发到其基础JwtSecurityContext
并因此返回我的Principal
,但是我不确定,最终我更喜欢使用我的JwtSecurityContext
而不是将这些值包装在Principal
实现.
Am I heading down a wrong path? Should I not be accessing my custom SecurityContext
in my resource method? One alternative could be to wrap all my data in the Principal
implementation I return from getUserPrincipal
in my JwtSecurityContext
. I suppose the proxy (SecurityContextInjectee
) would forward the call to its underlying JwtSecurityContext
and hence return my Principal
, but I am not sure, and ultimately I would prefer to use my JwtSecurityContext
instead of wrapping these values in a Principal
implementation.
推荐答案
您可以注入ContainerRequestContext
(如本文中所述),然后从那里获取SecurityContext
.
You can inject the ContainerRequestContext
(as mentioned in this post) and just get the SecurityContext
from there.
public List<SomeItem> getItems(@Context ContainerRequestContext context) {
JwtSecurityContext sec = (JwtSecurityContext)context.getSecurityContext();
}
这篇关于JAX-RS:自定义SecurityContext注入资源方法时具有意外类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!