gpt4 book ai didi

java - Jersey - 从过滤器中注入(inject)变量作为 RequestScoped

转载 作者:行者123 更新时间:2023-11-30 08:09:51 28 4
gpt4 key购买 nike

我想在调用我的资源方法之前在过滤器中执行身份验证。在这个过滤器中,我还想检索用户的权限并通过 RequestScoped @Inject 注释传递它。

@Authenticated
public class AuthenticationFilter implements ContainerRequestFilter {

@NameBinding
@Retention(RetentionPolicy.RUNTIME)
public @interface Authenticated {};

@Inject
private ISecurityHandler handler;

public AuthenticationFilter() {}

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

// Filter out unauthorized

// Retrieve user permissions
this.handler.setUserPermissions(...);
}
}

资源:

@Path("my-path")
public class GetVisitorsDataResource {

@Inject private ISecurityHandler handler;

@GET
@Path("resource-method")
@Authenticated
@Produces(MediaType.APPLICATION_JSON)
public Response resource() {

System.out.println(handler.getUserPermissions());

return Response.ok().build();
}
}

我已经为注入(inject)注册了过滤器和工厂。

public static class SecurityHandlerProvider implements Factory<ISecurityHandler> {

@Override
public ISecurityHandler provide() {
System.out.println("PROVIDING SECURITY CONTEXT!");
return new SecurityHandlerImpl();
}

@Override
public void dispose(ISecurityHandler instance) {
System.out.println("DISPOSING SECURITY CONTEXT!");
}
}

我也绑定(bind)了

bindFactory(SecurityHandlerProvider.class).to(ISecurityHandler.class).in(RequestScoped.class);

重要的是对象在收到请求时创建并且只能在该请求中访问。请求完成后,应调用 dispose 方法。我可以实现类似功能的唯一方法是通过 @Singleton 注释。但是,该对象不会在请求完成后销毁,而是在所有请求之间共享。

我已经在这个问题上投入了太多时间,也许有人知道如何获得理想的结果吗?

最佳答案

您的代码并没有多大意义。您在一个地方注入(inject) ISecurityHandler,在另一个地方注入(inject) SecurityHandler,但工厂用于 ISecurityContext。我将假定这些是拼写错误或复制粘贴错误。

除此之外,我假设一切正常,因为您说过它可以作为单例运行。所以我猜您遇到了“不在请求范围内” 错误。最简单的解决方法是使用 javax.inject.Provider 注入(inject),这允许我们懒惰地检索对象。检索对象时,它将在请求范围内。

@Inject
private javax.inject.Provider<ISecurityContext> securityContextProvider;

@Override
public void filter(ContainerRequestContext context) throws IOException {
ISecurityContext sc = securityContextProvider.get();
}

...
bindFactory(SecurityHandlerProvider.class)
.to(ISecurityContext.class)
.in(RequestScoped.class);

注意,您还应该确保使用 @Priority(Priorities.AUTHENTICATION) 注释您的 AuthenticationFilter,以便它出现在任何其他过滤器之前,即使您更喜欢它是一个 @PreMatching 过滤器。我认为越早进入系统进行身份验证越好。

顺便说一句,您可能想查看 Jersey 的 RolesAllowedDynamicFeature .它允许您对资源类和方法使用 jsr250 注释 @RolesAllowed@DenyAll@PermitAll

它基本上是一个发生在 Priorites.AUTHENTICATION 过滤器之后的过滤器,它从 中查找 javax.ws.rs.core.SecurityContext ContainerRequestContext 查找角色。您只需在身份验证过滤器中创建 SecurityContext,以便下一个过滤器可以查找它。

你可以看一个例子here .您可以在 isUserInRole 中检查用户权限。当设置SecurityContext时,Jersey 的过滤器将在之后调用,它会调用您的isUserInRole。这样做,您就可以免费获得访问控制。

关于java - Jersey - 从过滤器中注入(inject)变量作为 RequestScoped,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32073948/

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