【问题标题】:ContainerRequestFilter randomly giving nullContainerRequestFilter 随机给出 null
【发布时间】:2017-07-27 08:25:48
【问题描述】:

我有一个 Spring 4 + Jersey 2 Web 应用程序,它使用 JWT 进行身份验证。

我正在使用ContainerRequestFilter 拦截每个呼叫并检查请求是否具有正确的Authorization 令牌:

import java.util.Map;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.ext.Provider;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.auth0.jwt.JWT;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;

import my.beans.User;

@Provider
public class JWTFilter implements ContainerRequestFilter {
    private static final Logger LOG = LogManager.getLogger(JWTFilter.class);


    @Override
    public void filter(ContainerRequestContext context) {
        LOG.debug("JWT Filter");
        String authorization = context.getHeaderString("Authorization");
        if(authorization != null) {
            String jwtToken = authorization.replaceAll(".*Bearer\\s+", "");
            DecodedJWT jwt = JWT.decode(jwtToken);
            Map<String, Claim> claims = jwt.getClaims();
            String userid = claims.get("userid").asString();

            if(userid != null) {
                User user = loadUser(userid);

                // save user to request, so that it gets
                context.setProperty("loggedUser", user); 

                LOG.debug("User found: " + user);
            }
        } else {
            LOG.debug("JWT missing");
        }
    }

    private User loadUser(String userid) {
        // loads a User object
    }
}

然后我有一个BaseResource 类,它有一个getLoggedUser() 方法从ContainerRequestContext 检索数据:

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.core.Context;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import my.beans.User;

public class BaseResource {

    private static final Logger LOG = LogManager.getLogger(BaseResource.class);

    @Context
    private ContainerRequestContext context;

    public User getLoggedUser() {
        User u = (User) context.getProperty("loggedUser");
        LOG.debug("getLoggedUser(): " + u);
        return u;
    }

}

BaseResource 类由所有 Jersey 资源扩展。

这是我拥有的资源之一:

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;

import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;

import my.beans.User;

@Component
@Path("/test")
public class TestResource extends BaseResource {

    @GET
    @Produces(MediaType.APPLICATION_JSON_VALUE)
    @Path("/")
    public Response test() {
        User u = getLoggedUser();

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

如果我尝试执行这个资源,我会得到这个日志:

DEBUG: JWT Filter
DEBUG: User found: my.beans.User@4e7fb700
DEBUG: getLoggedUser(): my.beans.User@4e7fb700

它似乎有效。

如果我开始一次又一次地刷新页面,就会发生这种情况:

DEBUG: JWT Filter
DEBUG: User found: my.beans.User@4c0bea44
DEBUG: getLoggedUser(): my.beans.User@4c0bea44
DEBUG: JWT Filter
DEBUG: User found: my.beans.User@6ac29f24
DEBUG: getLoggedUser(): my.beans.User@6ac29f24
DEBUG: JWT Filter
DEBUG: User found: my.beans.User@668b07db
DEBUG: getLoggedUser(): null
DEBUG: JWT Filter
DEBUG: User found: my.beans.User@42fc180c
DEBUG: getLoggedUser(): my.beans.User@42fc180c

第三次,用户JWTFilter 类中找到,但在控制器内部出现null。这很奇怪,因为过滤器将它放在ContainerRequestContext 内,所以问题不应该发生。似乎有时ContainerRequestContext 无法保存数据,或者在到达控制器时丢失数据。

这里发生了什么?为什么我在调用ContainerRequestContest#getProperty时会随机得到null对象?我应该这样做吗?

值得一提的是,我的过滤器是javax.ws.rs.container.ContainerRequestFilter。我应该改用com.sun.jersey.spi.container.ContainerRequestFilter 吗?

【问题讨论】:

    标签: java spring jersey-2.0


    【解决方案1】:

    如果你想从过滤器获取数据到资源,尝试在过滤器类中设置http头,这样你就可以使用头参数进入资源类

    【讨论】:

    • 标头可以包含java对象吗?
    • 您可以将json对象转换为字符串并添加到header中。一旦您在资源中获取数据,使用jackson mapper转换回bean类中的json对象/map。
    • 不是json对象,是java对象。每次转换对象以将其作为标题传递时,对我来说似乎是不必要的开销。 ContainerRequestContext 应该在这里工作,我不需要使用标题。
    猜你喜欢
    • 1970-01-01
    • 2019-10-15
    • 1970-01-01
    • 2016-03-29
    • 1970-01-01
    • 2020-07-25
    • 2021-02-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多