前言:

使用springcloud及相关组件开发项目已有1年时间,从项目框架搭建-项目上线全程参与,目前项目已正常运行:我们也在不断的添砖添瓦,老项目也在不断转移至微服务。中间也遇到过很多问题,办法总比困难多,也都慢慢解决了。后续慢慢会把遇到的问题一一记录下来并提供解决方案,以供后续参考,今天主要记录下通过网关传递用户标识到其余下游服务。

问题描述:

Springcloud项目使用Spring Security OAuth2 SSO来实现登录权限控制,这里自然是没有问题的。问题来了:老项目springboot在向cloud项目转移过去的时候,很多请求接口都需要用到当前的一个用户信息,但是两个项目没有办法通过sso实现统一登录认证,如何解决呢

解决方案:

前段发起的所有请求的时候,在head里面添加加密的用户的唯一标识,cloud在网关进行过滤拦截,做出相应的处理,将用户标识通过addZuulRequestHeader进行转发到下游服务(有注意事项),但是只能传递下游一级服务,二级、三级服务如何获取呢,需要配合feignconfiguration 实现 RequestInterceptor来完成。

下面提供主要片段代码:

1.网关过滤器代码:

@Component
public class AccessFilterextends ZuulFilter {

    private static Logger log = LoggerFactory.getLogger(AccessFilter.class);
 
    @Override
    public String filterType() {
        //前置过滤器
        return "pre";
    }
 
    @Override
    public int filterOrder() {
        //优先级,数字越大,优先级越低
        return 0;
    }
 
    @Override
    public boolean shouldFilter() {
        //是否执行该过滤器,true代表需要过滤
        return true;
    }

 
    @Override
    public Object run() throws ZuulException {
        //向header中添加鉴权令牌
        RequestContext requestContext = RequestContext.getCurrentContext();
        //获取header
        HttpServletRequest request = requestContext.getRequest();
        String requestURI = request.getRequestURI();
        if(requestURI.contains("/api/front")){
            String authorization = request.getHeader("Authorization");
            if(StringUtils.isBlank(authorization)) {
                log.info("自行处理。。。。");
       
            }
         //此处需要注意addZuulRequestHeader 的 header命名最好都是小写,zuul过滤器会转成小写
         requestContext.addZuulRequestHeader("cur_user_id", authorization);


     }
       
        return null;
    }
}

2.获取用户信息的工具类

public class UserUtils{
     private static Logger log = LoggerFactory.getLogger(UserUtils.class);
     private static final String CUR_USER_ID = "cur_user_id";

    /**
     * 获取当前登录用户信息
     */
     public static String getId(){
         try {
             RequestAttributes requestAttributes = 
             RequestContextHolder.currentRequestAttributes();
             if (null == requestAttributes) {
                log.error("get request content is null ")
                return null;
             }
             HttpServletRequest request = ((ServletRequestAttributes)                     
             requestAttributes).getRequest();
             String curUserId = request.getHeader(CUR_USER_ID);
             if(StringUtils.isNotBlank(curUserId)){
                return "解密后的标识";
             }


            } catch (Exception e) {
                log.error("获取用户信息失败",e);
            }
            return null;
     }
}

3.FeignConfiguration的配置信息

@Configuration
public class FeignConfiguration implements RequestInterceptor{
    private final Logger logger = LoggerFactory.getLogger(getClass());
 
            @Override
            public void apply(RequestTemplate template) {
                ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
                        .getRequestAttributes();
                HttpServletRequest request = attributes.getRequest();
                Enumeration<String> headerNames = request.getHeaderNames();
                if (headerNames != null) {
                    while (headerNames.hasMoreElements()) {
                        String name = headerNames.nextElement();
                        String values = request.getHeader(name);
                        template.header(name, values);
 
                    }
                    logger.info("feign interceptor header:{}",template);
                }
               /* Enumeration<String> bodyNames = request.getParameterNames();
                StringBuffer body =new StringBuffer();
                if (bodyNames != null) {
                    while (bodyNames.hasMoreElements()) {
                        String name = bodyNames.nextElement();
                        String values = request.getParameter(name);
                        body.append(name).append("=").append(values).append("&");
                    }
                }
                if(body.length()!=0) {
                    body.deleteCharAt(body.length()-1);
                    template.body(body.toString());
                    //logger.info("feign interceptor body:{}",body.toString());
                }*/
            }
        }

4.未完成

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐