JAX-RS:自定义 SecurityContext 在注入资源方法时具有意外类型

2024-01-11

我已经实施了一个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());
        }
    }
}

如你所见,我更新了SecurityContext请求的,将其设置为我自己的自定义实现的实例(JwtSecurityContext) 如果验证成功。此实现添加了额外的身份验证和授权数据,我希望稍后在后续过滤器和资源方法中访问这些数据。

我还实施了一个AuthorizationFilter在之后立即调用AuthenticationFilter。在这里,我可以访问更新的JwtSecurityContext正好。

但是,当我尝试注入时遇到问题JwtSecurityContext到资源(方法)中。

我目前正在使用 Jersey,并且我在其文档中阅读了以下内容 https://jersey.java.net/documentation/latest/security.html#d0e12280:

The SecurityContext可以直接从中检索ContainerRequestContext via getSecurityContext()方法。你也可以 替换默认值SecurityContext在具有自定义的请求上下文中 一个使用setSecurityContext(SecurityContext)方法。如果您设置了 风俗SecurityContext实例在你的ContainerRequestFilter, 这 安全上下文实例将用于注入 JAX-RS 资源类字段。这样你就可以实现一个自定义的 可以设置您自己的身份验证过滤器SecurityContext成为 用过的。确保您的自定义身份验证的尽早执行 请求过滤器,将过滤器优先级设置为 AUTHENTICATION 使用 常数来自Priorities。尽早执行您的身份验证 过滤器将确保所有其他过滤器、资源、资源方法 子资源定位器将按照您的自定义执行SecurityContext实例。

我尝试注入JwtSecurityContext进入资源方法,如下所示:

@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.

我尝试过改变@Context SecurityContext securityContext to @Context JwtSecurityContext jwtSecurityContext,但如果我这样做,变量就会变成null。我也尝试过字段注入,但其行为是相同的。

我是否走错了路?我是否应该访问我的自定义SecurityContext在我的资源方法中?一种替代方法是将我的所有数据包装在Principal我返回的实现getUserPrincipal in my JwtSecurityContext。我想代理(SecurityContextInjectee) 会将调用转发给其底层JwtSecurityContext因此归还我的Principal,但我不确定,最终我更愿意使用我的JwtSecurityContext而不是将这些值包装在Principal执行。


您可以注入ContainerRequestContext(如中提到的这个帖子 https://stackoverflow.com/a/27666797/2587435)然后得到SecurityContext从那里。

public List<SomeItem> getItems(@Context ContainerRequestContext context) {
    JwtSecurityContext sec = (JwtSecurityContext)context.getSecurityContext();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JAX-RS:自定义 SecurityContext 在注入资源方法时具有意外类型 的相关文章

随机推荐