Spring Cloud Gateway实现网关统一鉴权,网关统一Token认证
Posted MateCloud微服务
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Cloud Gateway实现网关统一鉴权,网关统一Token认证相关的知识,希望对你有一定的参考价值。
需求背景
在微服务的场景下,采用了Spring Cloud Oauth2进行token的管理,实现认证和授权,在这下背景下,有两种解决方案:
网关统一鉴权
此模式适用于网关下的所有模式都是通过一种模式进行鉴权操作,可以统一管理
微服务模块各自鉴权
此模式适用于网关下的各个模块有不同的鉴权模式,针对不同的业务场景需要满足不同的实现,如采用oauth2、shiro、签名等方式。
下文就网关统一鉴权的实现方式提供解决方案,以供参考
实现方案
通过过滤器的方式实现统一拦截,下面以核心代码的方式展示,具体所有代码可以参考Matecloud项目。
过滤器代码
package vip.mate.gateway.filter;
import io.jsonwebtoken.Claims;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import vip.mate.core.cloud.props.MateUaaProperties;
import vip.mate.core.common.constant.MateConstant;
import vip.mate.core.common.constant.Oauth2Constant;
import vip.mate.core.common.util.ResponseUtil;
import vip.mate.core.common.util.SecurityUtil;
/**
* 网关统一的token验证
*
* @author pangu
*/
@Slf4j
@Component
@AllArgsConstructor
public class UaaFilter implements GlobalFilter, Ordered
private final MateUaaProperties mateUaaProperties;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain)
// 如果未启用网关验证,则跳过
if (!mateUaaProperties.getEnable())
return chain.filter(exchange);
log.error("getIgnoreUrl:", mateUaaProperties.getIgnoreUrl());
// 如果在忽略的url里,则跳过
String path = replacePrefix(exchange.getRequest().getURI().getPath());
String requestUrl = exchange.getRequest().getURI().getRawPath();
if (ignore(path) || ignore(requestUrl))
return chain.filter(exchange);
// 验证token是否有效
ServerHttpResponse resp = exchange.getResponse();
String headerToken = exchange.getRequest().getHeaders().getFirst(Oauth2Constant.HEADER_TOKEN);
if (headerToken == null)
return unauthorized(resp, "没有携带Token信息!");
Claims claims = SecurityUtil.getClaims(headerToken.replace("bearer ",""));
if (claims == null)
return unauthorized(resp, "token已过期或验证不正确!");
return chain.filter(exchange);
/**
* 检查是否忽略url
* @param path 路径
* @return boolean
*/
private boolean ignore(String path)
return mateUaaProperties.getIgnoreUrl().stream()
.map(url -> url.replace("/**", ""))
.anyMatch(path::startsWith);
/**
* 移除模块前缀
* @param path 路径
* @return String
*/
private String replacePrefix(String path)
if (path.startsWith("/mate"))
return path.substring(path.indexOf("/",1));
return path;
private Mono<Void> unauthorized(ServerHttpResponse resp, String msg)
return ResponseUtil.webFluxResponseWriter(resp, "application/json;charset=UTF-8", HttpStatus.UNAUTHORIZED, msg);
@Override
public int getOrder()
return MateConstant.MATE_UAA_FILTER_ORDER;
public static void main(String[] args)
方法上面也有注解,先通过注解的方式熟悉一下实现流程。
配置类
package vip.mate.core.cloud.props;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* 验证权限配置
*
* @author pangu
* @date 2020-10-28
*/
@Setter
@RefreshScope
@ConfigurationProperties(prefix = "mate.uaa")
public class MateUaaProperties
/**
* 忽略URL,List列表形式
*/
private List<String> ignoreUrl = new ArrayList<>();
/**
* 是否启用网关鉴权模式
*/
private Boolean enable = false;
/**
* 监控中心和swagger需要访问的url
*/
private static final String[] ENDPOINTS =
"/oauth/**",
"/actuator/**",
"/v2/api-docs/**",
"/v2/api-docs-ext/**",
"/swagger/api-docs",
"/swagger-ui.html",
"/doc.html",
"/swagger-resources/**",
"/webjars/**",
"/druid/**",
"/error/**",
"/assets/**",
"/auth/logout",
"/auth/code"
;
/**
* 自定义getter方法,并将ENDPOINTS加入至忽略URL列表
* @return List
*/
public List<String> getIgnoreUrl()
if (!ignoreUrl.contains("/doc.html"))
Collections.addAll(ignoreUrl, ENDPOINTS);
return ignoreUrl;
public Boolean getEnable()
return enable;
此配置类,主要配置忽略鉴权的URL和是否启用网关鉴权的开关。
其中需要在Nacos里增加如下配置,ignore-url配置的是忽略的url地址,在这里可以动态配置,并实时刷新。
mate:
uaa:
enable: false
ignore-url:
- /auth/login/**
- /auth/callback/**
- /auth/sms-code
至此,配置完成。
代码案例
MateCloud微服务:https://github.com/matevip/matecloud
以上是关于Spring Cloud Gateway实现网关统一鉴权,网关统一Token认证的主要内容,如果未能解决你的问题,请参考以下文章
使用 Spring Cloud Gateway 实现微服务 API 网关
spring cloud gateway + oauth2 实现网关统一权限认证
Java之 Spring Cloud 微服务搭建网关SpringCloud Gateway微服务网关GateWay(第三个阶段)SpringBoot项目实现商品服务器端是调用
Spring Cloud Gateway实现网关统一鉴权,网关统一Token认证
Java之 Spring Cloud 微服务搭建网关SpringCloud Gateway微服务网关GateWay(第三个阶段)SpringBoot项目实现商品服务器端是调用