gateway统一验证和解析token设置header

gateway统一验证和解析token设置header。比如设置userId,account等

package com.gateway.filter;

import com.alibaba.fastjson.JSONObject;
import com.gateway.auth.AccessException;
import com.gateway.auth.JwtTokenManager;
import com.gateway.auth.RolePowerServiceImpl;
import com.gateway.config.SkipConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;

/**
 * 网关跳转过滤类
 *
 * @Author: hans
 * @Date: 2020/05/23
 */
@Component
public class SkipFilter implements GlobalFilter, Ordered {

    private static final String URI = "/v2/api-docs";
    private static final String LOGIN = "/login";
    private static final String REGISTER = "/register";

    @Autowired
    private SkipConfig skipConfig;

    @Autowired
    private RolePowerServiceImpl rolePowerService;

    @Autowired
    private JwtTokenManager jwtTokenManager;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String url = request.getURI().getPath();
        if(StringUtils.endsWithIgnoreCase(url, URI) || StringUtils.endsWithIgnoreCase(url, LOGIN) || StringUtils.endsWithIgnoreCase(url, REGISTER)){
            return chain.filter(exchange);
        }
        String token = jwtTokenManager.resolveToken(request);
        try {
            if (!rolePowerService.perPermission(url)) {
                jwtTokenManager.validateToken(token);
                String uid = jwtTokenManager.getTokenId(token);
                rolePowerService.postPermission(uid, url);
            }
        } catch (AccessException e) {
            e.printStackTrace();
            return authError(exchange.getResponse(), e.getErrMsg());
        }

        /**
         * 1、验证经过网关的请求头中是否具有安全验证信息,若有则先删除
         * 2、在请求中添加安全头校验信息,并传递给各个微服务 --- 目前采用特定的key做为检验,后续需要结合redis进行安全校验
         */
        String key = "abcd";
        ServerHttpRequest newRequest = request.mutate()
                .headers(httpHeaders -> {
                    httpHeaders.remove(skipConfig.getSafeTransfers());
                })
                .header(CLAIM_KEY_ACCOUNT, user.getAccount())//header里面设置账号
                .build().mutate()
                .headers(httpHeaders -> {
                    httpHeaders.add(skipConfig.getSafeTransfers(), key);
                })
                .build();
        ServerWebExchange newExchange = exchange.mutate().request(newRequest).build();
        return chain.filter(newExchange);
    }

    @Override
    public int getOrder() {
        return -999;
    }

    /**
     * 认证错误输出
     *
     * @param resp 响应对象
     * @param mess 错误信息
     * @return
     */
    private Mono<Void> authError(ServerHttpResponse resp, String mess) {
        resp.setStatusCode(HttpStatus.UNAUTHORIZED);
        resp.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("message", mess);
        String returnStr = jsonObject.toJSONString();
        DataBuffer buffer = resp.bufferFactory().wrap(returnStr.getBytes(StandardCharsets.UTF_8));
        return resp.writeWith(Flux.just(buffer));
    }
}

  

posted on 2021-03-02 10:12  james-roger  阅读(533)  评论(0编辑  收藏  举报