本文主要内容是通过SpringCloud Gateway构建一个网关微服务,作为统一的认证授权和访问入口。
配置文件
先引入相关依赖,对应的pom文件内容如下:
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">
网关服务的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: '%d{HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n'
请求白名单配置
加载配置文件中的配置,注入到spring容器中。
secure:
ignore:
urls: # 配置白名单路径
- /actuator/**
- /auth/oauth/**
- /users/signin
/**
* 网关白名单配置
* @author zjq
*/
@Data
@Component
@ConfigurationProperties(prefix = "secure.ignore")
public class IgnoreUrlsConfig {
private List
}
异常处理和rest请求配置
异常处理在全局过滤器中会有用到,代码如下:
@Component
public class HandleException {
@Resource
private ObjectMapper objectMapper;
public Mono
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
// 判断当前的请求是否在白名单中
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
// 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;
}
}
测试验证
登录: 获取当前登录用户信息: 退出登录:
本文内容到此结束了, 如有收获欢迎点赞收藏关注✔️,您的鼓励是我最大的动力。 如有错误❌疑问欢迎各位指出。 主页:共饮一杯无的博客汇总
保持热爱,奔赴下一场山海。
文章来源
发表评论