我已经实现了执行基于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();
}

10-08 02:14