关于gateway与oauth2的兼容问题处理

文章目录

前言

令牌鉴权方案的选择上,比较流行的有spring security + 自定义的令牌(比如JWT令牌)、spring security+oauth2,假如使用了spring security + oauth2的方案,在使用上oauth2提供有ResourceServerTokenServices用于解决资源服务对令牌的权限的校验,当访问资源服务的时候,token令牌经过ResourceServerTokenServices的loadAuthentication方法完成验证。

但是当服务无需做非常细致的服务划分的时候,也就是将一个项目当做一个整体资源,这个时候就涉及到在网关校验即可,其他微服务无需二次校验。

问题

目前流行的网关方案是spring gateway(spring框架),但是gateway为了实现高效,底层使用Spring WebFlux,Spring WebFlux是Spring 5.0引入的新的响应式框架,区别于SpringMVC,它不需要依赖Servlet API,它是完全异步非阻塞的,所以引入oauth2-resource的时候会发现启动报错,配置需要基于servlet。

解决方案

手写RPC

手写http访问oauth2的check_token接口实现对token令牌的校验,实现起来比较简单,可以用在网关的过滤器上。下面举个例子

复制代码
  WebClient webClient = WebClient.create("http://localhost:9900");
        webClient.post()
                .uri("/oauth/check_token?token=" + token.substring(7))
                .header("Authorization", basic)
                .exchange()
                .flatMap(response -> {
                    HttpStatus status = response.statusCode();
                    if (status.is2xxSuccessful()) {
                        return response.bodyToMono(Map.class);
                    } else {
                        return response.createException().flatMap(Mono::error);
                    }
                }).subscribe(responseBody -> {
            log.info("post请求响应数据:{}", responseBody);
            if (Objects.isNull(responseBody) || responseBody.isEmpty()) {
                return;
            }
        }, error -> {
            log.error("post请求发生异常:", error);
        });

采用spring feign调用

据说在高版本需要对feign调用进行改造完成响应式的feign,因为spring自身并没有提供解决方案,暂时不在考虑范围。目前基于jdk8的最高版本也就是2.7.18,并没有这困扰。

下面Mono是用于测试响应式的feign调用

复制代码
@FeignClient(name = ServerNameConstant.AUTHORITY_CENTER, path = "/authorityCenter/auth", fallback = AuthRemoteFallback.class)
public interface AuthRemote {

    /**
     * 获取用户信息和权限
     *
     * @param in token
     * @return 用户信息
     * @author zfj
     * @date 2024/1/19
     */
    @PostMapping("/getUser")
    ResponseVO<UserResDTO> getUser(@RequestBody GetUserReqDTO in);

    /**
     * 获取用户信息和权限
     *
     * @param in token
     * @return 用户信息
     * @author zfj
     * @date 2024/1/19
     */
    @PostMapping("/getUserMono")
    Mono<ResponseVO<UserResDTO>> getUserMono(@RequestBody GetUserReqDTO in);

}

网关过滤器中调用

复制代码
ResponseVO<UserResDTO> res = oauthRemote.getUser(new GetUserReqDTO(token));

采用JWT解析

JWT具有去中心化的特点,也就能实现无需访问oauth2的鉴权服务就能自行解析令牌,但是也会带来风险,就是秘钥泄露,所以这种方案不能用于安全性要求高的服务。

oauth2也针对JWT提供一个方案(假设不是用resource依赖包,等你升级到spring 3版本以后就能知道了,低版本还可以用spring cloud oauth2,高版本就必须用resource),这个方案考虑到秘钥安全,采用数字自签证书实现公钥的分发,就能很好的避免伪造令牌问题(除非私钥也泄密,那就另外采取一套措施保护私钥)。

相关推荐
Raas1007 天前
MAI Gateway(魔芋企业级AI网关)功能全解:AI网关支持流式输出吗?一文看懂AI网关能力矩阵
大数据·人工智能·gateway·mai gateway·企业级网关
毅炼8 天前
不写多语言 SDK,怎么让 Python、Go、Node 服务接入注册中心?
java·后端·系统架构·gateway
Raas10011 天前
AI网关支持哪些模型?MAI Gateway(魔芋企业级AI网关)功能实测与最佳实践
大数据·人工智能·gateway·mai gateway·企业级产品
Raas10011 天前
MAI Gateway(魔芋企业级AI网关)技术揭秘:AI网关支持DeepSeek吗?从原理到落地
大数据·人工智能·gateway·ai网关·mai gateway·魔芋·企业级产品
Raas10012 天前
MAI Gateway(魔芋企业级AI网关)技术揭秘:AI网关支持哪些模型?从原理到落地
大数据·人工智能·网关·gateway·mai gateway·企业级产品
多云行者12 天前
什么是LLM Gateway?定义、技术栈与落地方式详解
网关·llm·gateway·api·传统
行者-全栈开发12 天前
Spring Boot 接入 MaxKey 单点登录:6 个内部系统,一次登录全通行
spring boot·iam·oauth2·统一认证·oidc·sso 单点登录·maxkey
不爱运动的跑者13 天前
OAuth 2.0 认证中心落地指南:Keycloak 26 打通 SSO、角色鉴权与令牌校验
keycloak·oauth2·认证中心
毅炼13 天前
Rover-Suite 开源发布:轻量服务注册中心与网关一体化方案
java·后端·系统架构·gateway