gpt4 book ai didi

jakarta-ee - 在 JAX-RS 请求过滤器之间共享数据的最佳方式

转载 作者:行者123 更新时间:2023-12-04 13:02:54 25 4
gpt4 key购买 nike

我想验证发出请求的用户。为此,我有两个过滤器:AuthenticationFilter 和 AuthorizationFilter。 AuthenticationFilter 从请求中提取 token 并从数据库中查找用户。 AuthorizationFilter 检查该用户(由前一个过滤器检索)是否具有必要的权限。我有两种可能的解决方案,想知道每种解决方案的优缺点以及我应该使用哪种解决方案。我还需要在实际业务逻辑中访问用户。我的代码如下:

身份验证过滤器:

@Secured
@Provider
@Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter {

// option 1.1
@Inject
@AuthenticatedUser
private Event<User> authenticatedUserEvent;

// option 1.2
@Inject
@AuthenticatedUser
private User authenticatedUser;

public void filter(ContainerRequestContext requestContext) throws IOException {
String token = getToken(requestContext);
User user = getUser(token)
if (user == null) {
requestContext.abortWith(...);
} else {
// option 1.1
authenticatedUserEvent.fire(User);

// option 1.2
authenticatedUser.setData(user);

// option 2
requestContext.setProperty("authenticatedUser", user);
}
}
}

授权过滤器:
@Secured
@Provider
@Priority(Priorities.AUTHORIZATION)
public class AuthorizationFilter implements ContainerRequestFilter {

@Context
private ResourceInfo resourceInfo;

// option 1
@Inject
@AuthenticatedUser
private User authenticatedUser;

public void filter(ContainerRequestContext requestContext) throws IOException {

// option 2
User authenticatedUser = (User) requestContext.getProperty("authenticatedUser")

boolean allowed = verifyRoles(user, resourceInfo.getResourceClass(), resourceInfo.getResourceMethod());
if (!allowed) {
requestContext.abortWith(...);
}
}
}

AuthenticatedUserProducer(仅适用于选项 1):
@RequestScoped
public class AuthenticatedUserProducer {

@Produces
@RequestScoped
@AuthenticatedUser
private User authenticatedUser;

public void handleAuthenticationEvent(@Observes @AuthenticatedUser User user) {
this.authenticatedUser = user
}
}

对于选项 1,是否需要使用 @RequestScoped 注释过滤器? ?默认情况下过滤器是应用程序范围的,那么注入(inject)安全吗?即,如果同时处理多个请求,请求链 1 中的过滤器 1 触发的事件不会最终注入(inject)链 2 的过滤器 2 中?在实际业务逻辑运行的资源类中注入(inject)用户时是否相同?

对于选项 2,我无法再访问 ContainerRequestContext ,但我可以通过注入(inject) HttpServletRequest 来访问该对象.但是这个选项在我看来“不太干净”,因为我必须在使用它们之前将存储的对象转换为 User,当使用注入(inject)方法时,我可以直接使用这些对象。

我已经检查了这些问题,我正在寻找的是确定哪个选项是最好的:
  • How to Pass Object from ContainerRequestFilter to Resource
  • Pass data from ContainerRequestFilter to Resource
  • Jax-RS Filter pass object to resource
  • What scope do JAX-RS 2 filters have?
  • Get resource class annotation values inside ContainerRequestFilter

  • 我目前正在使用 WildFly 11,其默认实现是 JAX-RS (Resteasy) 和 CDI (Weld)。

    最佳答案

    执行身份验证/授权后,您可以使用 SecurityContext ,它是 JAX-RS API 的一部分。查看如何在您的身份验证过滤器中使用它的示例:

    final SecurityContext currentSecurityContext = requestContext.getSecurityContext();
    requestContext.setSecurityContext(new SecurityContext() {

    @Override
    public Principal getUserPrincipal() {
    // Return a Principal instance according to your needs
    return () -> username;
    }

    @Override
    public boolean isUserInRole(String role) {
    return true;
    }

    @Override
    public boolean isSecure() {
    return currentSecurityContext.isSecure();
    }

    @Override
    public String getAuthenticationScheme() {
    // Return the authentication scheme used by your application
    return SecurityContext.BASIC_AUTH;
    }
    });

    然后注入(inject) SecurityContext 在您的 JAX-RS 资源和提供程序中使用 @Context注解:

    @Context
    SecurityContext securityContext;

    然后你可以得到 Principal SecurityContext 中设置的实例:

    Principal principal = securityContext.getUserPrincipal();

    关于jakarta-ee - 在 JAX-RS 请求过滤器之间共享数据的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51085328/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com