鍍金池/ 問答/云計算  Java/ Zuul 如何在pre Filter內(nèi)為request setAttribute

Zuul 如何在pre Filter內(nèi)為request setAttribute

我希望能在zuul的filter對request進行setAttribute("key",value)操作,然后在下游的服務(wù)能夠通過request.getAttribute("key")的方式獲取到數(shù)據(jù);但結(jié)果未如預(yù)期發(fā)生,在filter內(nèi)為request添加了attribute并未被傳遞到下游服務(wù)中;

/**
 * Created by zhaoyuening on 2018/1/26.
 */
@Component
public class TokenCheckFilter extends ZuulFilter {

    private final String JWT_HEADER_NAME = "token";
    private final Logger logger = LoggerFactory.getLogger(TokenCheckFilter.class);

    @Value("${token.filter}")
    private boolean IS_FILTER;

    @Autowired
    private RoleResourceManager roleResourceManager;

    @Override
    public String filterType() {
        return "pre";
    }

    @Override
    public int filterOrder() {
        return 5;
    }

    @Override
    public boolean shouldFilter() {
        if (IS_FILTER){
            logger.info("開啟token過濾");
        }else{
            logger.info("未開啟token過濾");
        }
        return IS_FILTER;
    }

    //超級管理員角色
    @Value("${root.role}")
    private String ROOT_ROLE;


    @Override
    //TODO 目前每次修改鑒權(quán)權(quán)限等信息 需要重啟
    //后續(xù)版本修改后采用mq 自動更新緩存
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        String url = request.getRequestURI();
        String method = request.getMethod();

        //檢測資源狀態(tài) 是否為白名單 或 被禁用
        // 0 白名單 1 被監(jiān)控權(quán)限 2 禁用
        Integer resourceStatus = roleResourceManager.checkStatusForResource(method, url);
        if (resourceStatus == null || resourceStatus == -1||resourceStatus == 2){
            createResponce("request fail!",ctx);
            return null;
        } else if (resourceStatus == 0){
            //白名單 放行
            return null;
        }

        //使用jwtBean解碼裝載jwt信息
        CodecUtils.JwtBean jwtBean = CodecUtils.JwtBean.getJwtBean(request.getHeader(JWT_HEADER_NAME));
        //將信息存儲到request
        addRequestAttribute(jwtBean,request);
        if (jwtBean != null){
            //jwt 用戶角色信息
            List<String> roleIdList = (List<String>) jwtBean.getPlayload(JwtFieldEnum.ROLES.getField());
            //指定id為1 的角色為超級管理員
            if (roleIdList != null && roleIdList.contains(ROOT_ROLE)){
                return null;
            }

            if (roleIdList != null && roleResourceManager.checkAuthority(method, url, roleIdList)) {
                //該檢驗通過 該用戶具備訪問資源的權(quán)限
                return null;
            }
        }
        //游客身份
        //查看是否為白名單Resource
        createResponce("request fail",ctx);
        return null;
    }

    /**
     * 請求失敗 調(diào)用
     * @param msg
     * @param ctx
     */
    private void createResponce(String msg,RequestContext ctx){
        // 過濾該請求,不對其進行路由
        ctx.setSendZuulResponse(false);
        // 返回?zé)o權(quán)限錯誤碼
        ctx.setResponseStatusCode(50008);
        // 返回錯誤內(nèi)容
        ctx.setResponseBody(msg);
        ctx.set("isSuccess", false);
    }

    /**
     * 從jwtBean獲取相應(yīng)信息,并加裝到request內(nèi)
     * @param jwtBean
     * @param request
     */
    private void addRequestAttribute(CodecUtils.JwtBean jwtBean,HttpServletRequest request) {
        if (jwtBean == null) {
            return;
        }
        //roles
        Object roles = jwtBean.getPlayload(JwtFieldEnum.ROLES.getField());
        Object username = jwtBean.getPlayload(JwtFieldEnum.USERNAME.getField());
        Object admin = jwtBean.getPlayload(JwtFieldEnum.ADMIN.getField());
        //save info to request
        request.setAttribute(RequestAttributeKeyEnum.ACCOUNT_ROLES.getKey(),roles);
        request.setAttribute(RequestAttributeKeyEnum.ACCOUNT_USERNAME.getKey(),username);
        request.setAttribute(RequestAttributeKeyEnum.ACCOUNT_ADMIN.getKey(),admin);

        RequestContext.getCurrentContext().setRequest(request);
    }
}

這是我的自定義pre filter 對request進行操作發(fā)生在最后的addRequestAttribute方法內(nèi),應(yīng)該如何操作讓下游接收到我在filter內(nèi)對request添加的數(shù)據(jù);

回答
編輯回答
夢一場

RequestContext#addZuulRequestHeader,傳遞的內(nèi)容,放在頭部。這樣下游應(yīng)用,可以從頭部獲取。

2017年3月5日 08:12
編輯回答
耍太極

問題解決了 setAttribute 只是以request對象為載體在單個程序內(nèi)傳輸?shù)臄?shù)據(jù),并在http規(guī)范中,不會被轉(zhuǎn)發(fā)到其他地方。只能采用requestHeader的方式來傳輸

2018年7月15日 19:14