Servlets jax rs 1.1带有安全过滤器和依赖注入,如何实现这一点?

Servlets jax rs 1.1带有安全过滤器和依赖注入,如何实现这一点?,servlets,jakarta-ee,jax-rs,cdi,servlet-filters,Servlets,Jakarta Ee,Jax Rs,Cdi,Servlet Filters,例如,我有以下JAX-RS 1.1方法,该方法接收、检查并处理或拒绝请求,如下所示: @GET public Response getBook(@HeaderParam("Authorization") String authorizationToken, @QueryParam("id") String bookId) { //if(authorizationToken is a valid JWT token) // get User object which r

例如,我有以下JAX-RS 1.1方法,该方法接收、检查并处理或拒绝请求,如下所示:

@GET
public Response getBook(@HeaderParam("Authorization") String authorizationToken, @QueryParam("id") String bookId) {

    //if(authorizationToken is a valid JWT token)
    //      get User object which represented by this token
    //      get required book from database
    //      return 200 code with a book within response
    //else if(authorizationToken is invalid by whatever reason it's)
    //      return 401 code within a response
    //else if(database error)
    //      return 500 code within a response

}
@GET
public Response getBook(@RequestByUser User user, @QueryParam("id") String bookId) {

    //if(get required book from database was successfull)
    //      return 200 code with a book within response
    //else(database error)
    //      return 500 code within a response
}
正如您在每个jax-rs方法中看到的,我需要使用相同的代码行:检查令牌,将其转换为
User
对象,如果无效,则返回401错误

实际上,我可以通过在静态方法中提取它来优化它,该方法将执行此检查,并在成功时返回
用户
对象,或者在出现问题时抛出
异常
。我还可以创建一个在到达jax-rs方法之前检查报头和验证令牌的方法,如果无效,将以401异常中止它

但我想一起实现这一切
Webfilter
将验证JWT令牌,如果它有效则将其转换为
User
对象,并在jax rs方法中注入它,如下所示:

@GET
public Response getBook(@HeaderParam("Authorization") String authorizationToken, @QueryParam("id") String bookId) {

    //if(authorizationToken is a valid JWT token)
    //      get User object which represented by this token
    //      get required book from database
    //      return 200 code with a book within response
    //else if(authorizationToken is invalid by whatever reason it's)
    //      return 401 code within a response
    //else if(database error)
    //      return 500 code within a response

}
@GET
public Response getBook(@RequestByUser User user, @QueryParam("id") String bookId) {

    //if(get required book from database was successfull)
    //      return 200 code with a book within response
    //else(database error)
    //      return 500 code within a response
}

所以,若我达到那个点,我可以确定用户是有效的,我不需要关心它。使用JAX-RS 1.1有可能实现这一点吗?

我不知道有什么方法可以完全满足您的要求,但是用一些工具实现一些东西并不太难。基本上,过滤器将存储ThreadLocal数据和用户信息,服务方法将能够获取这些信息。这是一个有点黑客,但它会让你做你想做的

但是要小心-线程本地数据与线程一起存在-尽量不要在其中存储一个巨大的对象,否则如果有大量客户端,您可能会遇到内存问题

编辑

仔细考虑一下,为什么不直接使用会话呢?ThreadLocal假定筛选器和服务在同一线程上运行。这可能是真的,但不能保证

因此,在过滤器中:

JWTFilter.java

YourService.java

注意这里的“欺骗”——我们正在注入HttpServletRequest,以便获得会话以及用户。但是由于过滤器的原因,如果JWT验证失败,将不会调用此方法


这段代码没有利用JAX-RS和/或Servlet规范之外的任何东西,应该与应用程序服务器无关。

您可以为此使用过滤器和/或拦截器。这是一个例子

public class AuthorizationRequestFilter implements ContainerRequestFilter {

    @Override
    public void filter(ContainerRequestContext requestContext)
                    throws IOException {

        final SecurityContext securityContext =
                    requestContext.getSecurityContext();
        if (securityContext == null ||
                    !securityContext.isUserInRole("privileged")) {

                requestContext.abortWith(Response
                    .status(Response.Status.UNAUTHORIZED)
                    .entity("User cannot access the resource.")
                    .build());
        }
    }
}

我提到我需要jax rs 1.1的解决方案,
ContainerRequestFilter
,因为只有2.0才可用。您好,WebFilter来自哪个包。它是jax-rs 1.1的一部分吗?jax-rs 1.1已经在类路径中,但是WebFilter导入无法解析。你能不能请他;P