栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【无标题】Spring Cloud Gateway 与权限认证

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【无标题】Spring Cloud Gateway 与权限认证

服务网关的概念有点类似于传统的反向代理服务器(如nginx),但反向代理一般都只是做业务无关的转发请求,而服务网关与服务的整合程度更高,可以看作也是整个服务体系的组成部分,通过过滤器等组件可以在网关中集成一些业务处理的操作(比如权限认证等)。Spring Cloud Gateway正是Spring官方推出的服务网关的实现框架,它主要包含三个核心的概念:

Route: 负责将某个外部请求路由到一个合适的地址,包含一个ID,一个目标地址,一系列的Predicate和Filter;
Predicate: 基于Java 8 Function Predicate的断言机制,用于将请求匹配到某一个Route
Filter: 类似于Servlet filter,可以在请求传递给下一级处理器之前对请求或响应进行修改,用于实现权限验证,日志记录,限流等功能

网关集成

我们现在来为我们的demo项目加入一个服务网关。首先需要创建一个新的模块,名字叫Gateway,在pom.xml中加入如下依赖:

org.springframework.cloud spring-cloud-starter-gateway

在application.yml中加入如下内容:

server:
  port: 9000

spring:
  application:
    name: gateway
  cloud:
    consul:
      host: 192.168.1.220
      port: 8500
      discovery:
        prefer-ip-address: true
    gateway:
      routes:
        - id: order-service
          #lb协议会激活LoadBalancerClient来解析后续的地址,自动根据注册的服务实例进行负载均衡
          uri: lb://order-service
          filters:
            - Log
            # 转发时去掉请求地址的服务名前缀
            - StripPrefix=1
          predicates:
            - Path=/order-service
    @Override
    public int getOrder() {
        return 1;
    }

}
功能很简单,就是对请求头部的token进行校验,如果成功就将从token中解析出来的用户账户信息放入转发的请求头中供后端的业务服务使用,否则返回UNAUTHORIZED。这个Filter也需要注册到容器中:

    @Bean
    public AuthGlobalFilter authGlobalFilter(AuthService authService) {
        return new AuthGlobalFilter(authConfig, authService);
    }
对token进行校验的核心逻辑在authService.verifyToken方法中,代码如下:

 
    public boolean verifyToken(String url, String token) {
        if (Strings.isNullOrEmpty(token)) {
            return false;
        }
        //获取每个Url所对应的权限控制符
        String urlPermission = getUrlPermission(url);
        if ("anno".equals(urlPermission)) {
            return true;
        } else {
            //获取token中包含的用户唯一标识
            String account = jwtHelper.getAccount(token);
            if (Strings.isNullOrEmpty(account)) {
                return false;
            }
            //获取token的加密密钥
            String secret = getUserSecret(account);
            //校验accessToken
            if (jwtHelper.verify(token, secret) == null) {
                return false;
            }
            // 如果url仅要求验证用户有效性,则直接通过
            if (Strings.isNullOrEmpty(urlPermission) ||
                    "authc".equals(urlPermission)) {
                return true;
            }
            // 进一步判断用户权限
            if (urlPermission.startsWith("perms")) {
                Set userPerms = this.getUserPermissions(account);
                String perms = urlPermission.substring(urlPermission.indexOf("[") + 1, urlPermission.lastIndexOf("]"));
                return userPerms.containsAll(Arrays.asList(perms.split(",")));
            }
        }
        return false;
    }

服务网关首先需要知道不同的服务地址需要什么样的权限才允许访问,这里采用了类似Shiro配置的格式,类似这样如下的格式,实际环境中可能是从数据库或配置文件中读取:

 
    public Map getAllUrlPermissionsMap() {
        Map urlPermissionsMap = Maps.newHashMap();
        urlPermissionsMap.put("/api/order/orders", "authc");
        urlPermissionsMap.put("/api/order/create-order", "perms[order]");
        urlPermissionsMap.put("/api/storage/**", "perms[storage]");
        return urlPermissionsMap;
    }

通过Spring 提供的工具类AntPathMatcher,就可以查询到每个请求url所需要的权限标识符,再根据权限标识符去检查token对应的用户是否具备相应的权限
引用该文章,点击查看详情。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/631462.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号