相关文章推荐
直爽的萝卜  ·  Stable ...·  2 月前    · 

在微服务的场景下,采用了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 Oauth2进行token的管理,实现认证和授权,在这下背景下,有两种解决方案:网关统一鉴权此模式适用于网关下的所有模式都是通过一种模式进行鉴权操作,可以统一管理微服务模块各自鉴权此模式适用于网关下的各个模块有不同的鉴权模式,针对不同的业务场景需要满足不同的实现,如采用oauth2、shiro、签名等方式。下文就网关统一鉴权的实现方式提供解决方案,以供参考实现方案通过过滤器的方式实现统一拦截,下面以核心代码的方式展示,具体所有代码可以 一,统一鉴权 内置的过滤器已经可以完成大部分的功能,但是对于企业开发的一些业务功能处理,还是需要我们自己 编写过滤器来实现的,那么我们一起通过代码的形式自定义一个过滤器,去完成统一的权限校验。 1.1 鉴权逻辑 开发中的鉴权逻辑: 当客户端第一次请求服务时,服务端对用户进行信息认证(登录) 认证通过,将用户信息进行加密形成token,返回给客户端,作为登录凭证 以后每次请求,客户端都携带认证token
一个简单的微服务 包含鉴权服务auth-service,网关服务gateway-service,业务层api-service 所有服务基于spring boot 2.2.0.RELEASE和spring cloud Hoxton.M3进行开发。 api-service是业务服务,提供业务接口,没有token验证; 通过gateway-service可以访问api-service的业务接口,并在gateway实现统一的用户认证; auth-service提供用户认证和用户鉴权能力。 认证服务 使用spring cloud oauth2,实现一个简单的基本的oauth2 provider 使用jwt令牌,使用自定义JwtTokenStore 提供/.well-known/jwks.json端点 网关服务 使用spring cloud gateway实现简单路由 作为oauth2资源服务器加入auth-service API服务 提供简单的Restful API,通过gateway-service调用 依次运行auth-service,gateway-service,api-s
基础名词概念 **权限:**属于系统的安全范畴,权限管理实现对用户访问系统的控制,按照安全规则或者安全控制策略用户可以访问而且只能访问自己被授权的资源,主要包括用户身份认证和请求鉴权两部分,简称认证鉴权 认证判断一个用户是否为合法用户的处理过程,最常用的简单身份认证是系统通过核对用户输入的用户名和口令,看其是否与系统中存储的该用户的用户名和口令一致,来判断用户身份是否正确 鉴权:即访问控制,控制谁能访问那些资源;进行身份认证后需要分配权限可访问的系统资源,对于某些资源没有权限是无法访问的,如下图所示
一、JWT 实现微服务鉴权 JWT一般用于实现单点登录。单点登录:如腾讯下的游戏有很多,包括lol,飞车等,在qq游戏对战平台上登录一次,然后这些不同的平台都可以直接登陆进去了,这就是单点登录的使用场景。JWT就是实现单点登录的一种技术,其他的还有oath2等。 1 什么是微服务鉴权 我们之前已经搭建过了网关,使用网关网关系统中比较适合进行权限校验。 那么我们可以采用JWT的方式来实现鉴权校验。 2.代码实现 1. 用户进入网关开始登陆,网关过滤器进行判断,如果是登录,则路由到后台管理微服务
查看当前依赖最新版本 了解更多过关于更多信息; 路由网关:基于spring cloud gateway,进行api请求的转发,当前会路由到leafage-basic模块的两个后台服务,资产和管理程序; 安全保护:整合spring security,实现了表单登录的功能,因为前一次分离分离,所以对登录的基本配置进行了一些修改,本项目中没有使用通常其他项目中使用的jwt来做,原因有: 前端都是基于浏览器访问,可以使用cookie,并且实现了csrf防御,并且基于nginx和gateway双重请求的保护规则,安全可靠,且简单实用; jwt这个东西太重了,而且很不安全,因为安全原因,不会将用户用户名之外的任何信息放进token,所以单单为了username这个而在请求中每
VMware的Spring Cloud Gateway商业产品的示例应用程序。 我们通过此示例应用程序演示的功能: 使用容器到容器网络将流量路由到已配置的内部路由 通过服务绑定配置的网关路由 简化的路由配置 代表路由服务的SSO登录和令牌中继 路由的必需范围(标记: require-sso-scopes ) 断路器过滤器 部署到Kubernetes Kubernetes部署需要您安装 。 您还需要将成功安装到目标Kubernetes集群上。 配置单点登录(SSO) 为了使Animal Rescue示例单点登录(SSO)正常工作,您需要创建两个文本文件,这些文件将用于创建Kubernetes机密: ./backend/secrets/sso-credentials.txt ./gateway/sso-secret-for-gateway/secrets/test 网关服务 包含 网关 http , websocket 两种转发包含网关 ,包含webSocket消息发送的流量监控 UserApplication 模拟WebSocket服务 PtGateClientTests 模拟WebSocket请求服务 http可以通过网页模拟 (开启鉴权之后需要postman在header中添加token才能通过鉴权) 导入之后 maven跑完即可完整运行
jwt springcloud,修复了刷新tokenbug, 注意修改下端口网关 登录认证地址 http://localhost:8764/openplt/auth/login 刷新tocken 地址 http://localhost:8764/openplt/auth/refresh_token,详情参考 https://www.jb51.net/article/133832.htm 原始作者
应用架构: 认证服务负责认证网关负责校验认证鉴权,其他API服务负责处理自己的业务逻辑。 安全相关的逻辑只存在于认证服务和网关服务中,其他服务只是单纯地提供服务而没有任何安全相关逻辑。 JWT认证流程: 1、用户使用账号和密码发出post请求; 2、服务器使用私钥创建一个jwt; 3、服务器返回这个jwt给浏览器; 4、浏览器将该jwt串在请求头中像服务器发送请求; 5、服务器验证该jwt; 6、返回响应的资源给浏览器。 JWT解析 JWT使用场景: 授权:这是JWT使用最多的场景,一旦用户登
Spring Cloud Gateway 是一个非常流行的微服务网关,在微服务架构设计中有着重要的作用,可以用来实现各种功能,例如路由转发、负载均衡、流量控制、限流等;除此之外,Spring Cloud Gateway 还能够支持统一认证,即只需要一次认证,就能够访问所有的微服务,这对于复杂的微服务架构来说非常的有用。 实现统一认证实现方法如下: 1. 接入认证中心:首先需要在 Spring Cloud Gateway 中接入一个认证中心,比如使用 Spring Security 或 OAuth2 进行认证实现单点登录。 2. 统一身份验证:在用户登录认证成功之后,会生成一个 tokenSpring Cloud Gateway 会通过这个 token 来进行用户身份认证。而在微服务中,只需要进行简单的 token 验证就能够获取到用户信息,并进行相应的操作。 3. 统一资源管理:在认证中心中进行配置,指定可以访问的资源,进而限制了用户访问微服务的范围。这样就能够确保只有获得了相应权限的用户才能够访问微服务。 4. 日志跟踪:Spring Cloud Gateway 还能够记录每个请求的详细信息和用户信息,进而进行日志跟踪和监控,这对于故障排除和性能优化非常重要。 总之,实现 Spring Cloud Gateway统一认证,能够提供更好的安全性,同时提高开发效率,显著降低了微服务的管理难度,减轻了微服务的管理负担。
<!-- https://mvnrepository.com/artifact/vip.mate/mate-starter-common --> <dependency> <groupId>vip.mate</groupId> <artifactId>mate-starter-common</artifactId> <version>2.3.8</version> </dependency> </dependencies>