SpringCloud Gateway网关为认证中心和用户微服务构建统一的认证授权入口
Posted Java知音_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringCloud Gateway网关为认证中心和用户微服务构建统一的认证授权入口相关的知识,希望对你有一定的参考价值。
点击关注公众号,实用技术文章及时了解
本文主要内容是通过SpringCloud Gateway构建一个网关微服务,作为统一的认证授权和访问入口。
配置文件
先引入相关依赖,对应的pom文件内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>oauth2-demo</artifactId>
<groupId>com.zjq</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ms-gateway</artifactId>
<dependencies>
<!-- spring cloud gateway -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- eureka client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- commons 公共项目 -->
<dependency>
<groupId>com.zjq</groupId>
<artifactId>commons</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 和 webflux 冲突 -->
<exclusions>
<exclusion>
<groupId>com.battcn</groupId>
<artifactId>swagger-spring-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 自定义的元数据依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>
网关服务的yml配置内容如下:
server:
port: 80
spring:
application:
name: ms-gateway
cloud:
gateway:
discovery:
locator:
enabled: true # 开启配置注册中心进行路由功能
lower-case-service-id: true # 将服务名称转小写
routes:
- id: ms-users
uri: lb://ms-users
predicates:
- Path=/users/**
filters:
- StripPrefix=1
- id: ms-oauth2-server
uri: lb://ms-oauth2-server
predicates:
- Path=/auth/**
filters:
- StripPrefix=1
secure:
ignore:
urls: # 配置白名单路径
- /actuator/**
- /auth/oauth/**
- /users/signin
# 配置 Eureka Server 注册中心
eureka:
instance:
prefer-ip-address: true
instance-id: $spring.cloud.client.ip-address:$server.port
client:
service-url:
defaultZone: http://localhost:7000/eureka/
logging:
pattern:
console: '%dHH:mm:ss [%thread] %-5level %logger50 - %msg%n'
请求白名单配置
加载配置文件中的配置,注入到spring容器中。
secure:
ignore:
urls: # 配置白名单路径
- /actuator/**
- /auth/oauth/**
- /users/signin
/**
* 网关白名单配置
* @author zjq
*/
@Data
@Component
@ConfigurationProperties(prefix = "secure.ignore")
public class IgnoreUrlsConfig
private List<String> urls;
异常处理和rest请求配置
异常处理在全局过滤器中会有用到,代码如下:
@Component
public class HandleException
@Resource
private ObjectMapper objectMapper;
public Mono<Void> writeError(ServerWebExchange exchange, String error)
ServerHttpResponse response = exchange.getResponse();
ServerHttpRequest request = exchange.getRequest();
response.setStatusCode(HttpStatus.OK);
response.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
ResultInfo resultInfo = ResultInfoUtil.buildError(ApiConstant.NO_LOGIN_CODE, ApiConstant.NO_LOGIN_MESSAGE, request.getURI().getPath());
String resultInfoJson = null;
DataBuffer buffer = null;
try
resultInfoJson = objectMapper.writeValueAsString(resultInfo);
buffer = response.bufferFactory().wrap(resultInfoJson.getBytes(Charset.forName("UTF-8")));
catch (JsonProcessingException ex)
ex.printStackTrace();
return response.writeWith(Mono.just(buffer));
申请授权和认证过程中需要远程调用其他接口,所以我们引入rest请求配置,代码如下:
/**
* REST请求配置
* @author zjq
*/
@Configuration
public class RestTemplateConfiguration
@LoadBalanced
@Bean
public RestTemplate restTemplate()
return new RestTemplate();
全局过滤器配置
配置好了白名单,我们需要在网关过滤器中使用该白名单配置,放行对应的白名单,网关过滤器需要实现全局过滤器接口org.springframework.cloud.gateway.filter.GlobalFilter
和过滤器顺序接口org.springframework.core.Ordered
相关代码如下:
/**
* 网关全局过滤器
* @author zjq
*/
@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered
@Resource
private IgnoreUrlsConfig ignoreUrlsConfig;
@Resource
private RestTemplate restTemplate;
@Resource
private HandleException handleException;
/**
* 身份校验处理
*
* @param exchange
* @param chain
* @return
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain)
// 判断当前的请求是否在白名单中
AntPathMatcher pathMatcher = new AntPathMatcher();
boolean flag = false;
String path = exchange.getRequest().getURI().getPath();
for (String url : ignoreUrlsConfig.getUrls())
if (pathMatcher.match(url, path))
flag = true;
break;
// 白名单放行
if (flag)
return chain.filter(exchange);
// 获取 access_token
String access_token = exchange.getRequest().getQueryParams().getFirst("access_token");
// 判断 access_token 是否为空
if (StringUtils.isBlank(access_token))
return handleException.writeError(exchange, "请登录");
// 校验 token 是否有效
String checkTokenUrl = "http://ms-oauth2-server/oauth/check_token?token=".concat(access_token);
try
// 发送远程请求,验证 token
ResponseEntity<String> entity = restTemplate.getForEntity(checkTokenUrl, String.class);
// token 无效的业务逻辑处理
if (entity.getStatusCode() != HttpStatus.OK)
return handleException.writeError(exchange,
"Token was not recognised, token: ".concat(access_token));
if (StringUtils.isBlank(entity.getBody()))
return handleException.writeError(exchange,
"This token is invalid: ".concat(access_token));
catch (Exception e)
return handleException.writeError(exchange,
"Token was not recognised, token: ".concat(access_token));
// 放行
return chain.filter(exchange);
/**
* 网关过滤器的排序,数字越小优先级越高
*
* @return
*/
@Override
public int getOrder()
return 0;
测试验证
登录:
获取当前登录用户信息:
退出登录:
感谢阅读,希望对你有所帮助 :)
来源:zhanjq.blog.csdn.net/article/details/127574020
推荐
Java面试题宝典
技术内卷群,一起来学习!!
PS:因为公众号平台更改了推送规则,如果不想错过内容,记得读完点一下“在看”,加个“星标”,这样每次新文章推送才会第一时间出现在你的订阅列表里。点“在看”支持我们吧!
以上是关于SpringCloud Gateway网关为认证中心和用户微服务构建统一的认证授权入口的主要内容,如果未能解决你的问题,请参考以下文章
SpringCloud系列之网关gateway-11.权限认证-分布式session替代方案