JAX-RS:自定义SecurityContext注入资源方法时具有意外类型 [英] JAX-RS: Custom SecurityContext has unexpected type when injected into resource method

查看:116
本文介绍了JAX-RS:自定义SecurityContext注入资源方法时具有意外类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经实现了执行基于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,该AuthorizationFilterAuthenticationFilter之后立即被调用.在这里,我可以正常访问更新的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设置为 用过的.为了确保尽早执行您的自定义身份验证 请求过滤器,使用以下命令将过滤器优先级设置为AUTHENTICATION Priorities中的常量.尽早执行身份验证 过滤器将确保所有其他过滤器,资源,资源方法 和子资源定位器将按照您的自定义执行 SecurityContext实例.

The SecurityContext can be directly retrieved from ContainerRequestContext via getSecurityContext() method. You can also replace the default SecurityContext in a request context with a custom one using the setSecurityContext(SecurityContext) method. If you set a custom SecurityContext instance in your ContainerRequestFilter, 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 own SecurityContext to be used. To ensure the early execution of your custom authentication request filter, set the filter priority to AUTHENTICATION using constants from Priorities. An early execution of you authentication filter will ensure that all other filters, resources, resource methods and sub-resource locators will execute with your custom SecurityContext 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆