0

我们最近通过“guice-bridge”将 Guice 与 Jersey 集成,并且必须在此过程中升级依赖版本。但是随后在生产中的子资源(只有它们)有时会注入错误的 SecurityContext,而主体来自另一个线程!这种行为似乎是完全随机的,以前从未出现过。我们如何解决这个问题?

这是身份验证过滤器:

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

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        // abort if user is not authenticated
        requestContext.setSecurityContext(new MySecurityContext(...));
      }
}

这是根资源:

@Path("/root-resource")
public class RootResource extends BaseResource {

    @Path("{rootResourceId}/sub-resource")
    public SubResource subResource(@PathParam("rootResourceId") String id) {
        return SubResource.create(this, id);
    }

    ...
}

这是子资源:

@Provider
public class SubResource extends BaseResource {

    public static SubResource create(RootResource root, String rootResourceId) {
        SubResource r = root.createSubResource(SubResource.class);
        ... // further setup
        return r;
    }

    @PUT
    @Path("{subResourceId}")
    public void update(@PathParam("subResourceId") String subResourceId) {
        checkUserHasAccessToResource(subResourceId, context); // BOOM ?#!
        ...
    }   
}

这是基类:

public abstract class BaseResource {

    private ResourceContext resourceContext;
    private SecurityContext securityContext;

    protected final <T extends AuthResource> T createSubResource(Class<T> resourceClass) {
        return resourceContext.getResource(resourceClass);
    }

    ...

    @Context
    public void setResourceContext(ResourceContext resourceContext) {
        this.resourceContext = resourceContext;
    }

    @Context
    public void setSecurityContext(SecurityContext securityContext) {
        this.securityContext = securityContext;
    }
}

PS:我们使用 JDK7、Jersey 2.10.2 和 HK2 2.3.0-b04。

编辑

SecurityContext 实现:

public class MySecurityContext implements SecurityContext {

    private final MyUserPrincipal userPrincipal;
    private final boolean isSecure;
    private final String authScheme;

    public MySecurityContext(MyUserPrincipal userPrincipal, boolean isSecure, String authScheme) {
        this.userPrincipal = userPrincipal;
        this.isSecure = isSecure;
        this.authScheme = authScheme;
    }

    @Override
    public Principal getUserPrincipal() {
        return userPrincipal;
    }

    @Override
    public boolean isUserInRole(String role) {
        return userPrincipal.isInRole(role);
    }

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

    @Override
    public String getAuthenticationScheme() {
        return authScheme;
    }
}

还有校长:

public class MyUserPrincipal implements Principal {

    private String userId;
    private String userName;
    private String[] roles;

    public MyUserPrincipal(String userId, String userName, String[] roles) {
        this.roles = roles;
        this.userId = userId;
        this.userName = userName;
    }

    @Override
    public String getName() {
        return userName;
    }

    @Override
    public String toString() {
        return userName + " (" + userId + ")";
    }

    @Override
    public boolean isSecureLogin() {
        return true;
    }

    @Override
    public void reloadUser() {
    }

    public boolean isInRole(String role) {
        ...
    }
}
4

1 回答 1

0

在尝试了几个其他版本的 HK2 之后,这种行为就停止了。害怕。

于 2014-09-04T12:46:22.687 回答