Spring Cloud GateWay自定义auth 认证授权
使用custom-auth+Spring-Gateway+Nacos+Redis的微服务授权Demo案例。
主要使用技术栈:
- Alibaba-Nacos注册中心
- SpringCloud-GateWay网关
- custom-auth
- Redis缓存存储
- MyBatis-plus
- Feign HTTP客户端
授权步骤:
-
认证 利用网关 使用db-auth Login接口登录, 其中默认登录用户:18888888888密码123456
请求路径 POST(http://localhost:9527/nocas-auth/sys/login/login RequestBody:{"phone":"18888888888","password":"123456"})
-
GET登录后,请求返回Result JSON,内含授权Token
-
授权利用网关 使用db-auth SysUserController接口进行获取登录信息,模拟接口授权
请求路径GET(http://localhost:9527/nocas-auth/sys/user/test) 请求头新增 “token”内容,用于前后分离时身份认证
-
鉴权 请求路径+token 执行GateWay-->AuthFilter
流程图
贴部分认证授权代码
gateway:application.yml
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848 #配置Nacos地址
gateway:
discovery:
locator:
enabled: true #开启从注册中心动态创建路由的功能
lower-case-service-id: true #使用小写服务名,默认是大写
routes:
- id: payment_route #路由的ID
uri: lb://nacos-payment-service
predicates: # 断言,路径相匹配的进行路由
- Path=/nacos-payment-service/**
filters:
- StripPrefix=1
- id: auth_route #路由的ID
uri: lb://nacos-auth
predicates: # 断言,路径相匹配的进行路由
- Path=/nacos-auth/**
filters:
- StripPrefix=1
- Token=token #注意:TokenGatewayFilterFactory,只需要写Token
认证 (authentication)
@Component
@Slf4j
public class TokenGatewayFilterFactory extends AbstractGatewayFilterFactory<TokenGatewayFilterFactory.Config> implements Ordered {
@Autowired
private AuthExclusion exclusion;
@Autowired
private AuthService authService;
/**
*
* db-common {@link com.duobang.cloud.response.MyResponseCode.UNAUTHENTICATED}
*/
private final String UNAUTHENTICATED = "40100";
public TokenGatewayFilterFactory() {
super(Config.class);
}
@Override
public List<String> shortcutFieldOrder() {
return Lists.newArrayList("token");
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
ServerHttpResponse response = exchange.getResponse();
String path = exchange.getRequest().getPath().toString();
log.info("path:[{}]", path);
//1、判断是否是过滤的路径, 是的话就放行
if (exclusion.isExclusionUrl(path) ){
return chain.filter(exchange);
}
String tokenValue = exchange.getRequest().getHeaders().getFirst(config.getToken());
log.info("从请求中获取到的token value 是:[{}]", tokenValue);
// token是否存在
if(StrUtil.isBlank(tokenValue) || !authService.checkToken(tokenValue)){
throw new AuthenticatedException("未登录");
}
return chain.filter(exchange);
};
}
@Override
public int getOrder() {
return 1;
}
@Data
public static class Config {
private String token;
}
}
授权 (authorization)
@Slf4j
@Component
public class AuthFilter implements GlobalFilter, Ordered {
@Autowired
private AuthExclusion exclusion;
@Autowired
private AuthService authService;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String path = exchange.getRequest().getPath().toString();
//判断请求的URL是否有权限
if(!authService.checkAuth(request)){
throw new ForbiddenException("无访问权限");
}
return chain.filter(exchange.mutate().request(request).build());
}
/**
* 指定全局过滤器执行的顺序
*
* @return
*/
@Override
public int getOrder() {
return 2;
}
文末
第一次编译前:db-auth8088 modlues
类名:com.duobang.cloud.runner.DataRunner
并修改applicaiton.yml
准备源数据
auth:
prepare-data: true