SpringCloud Gateway网关为认证中心和用户微服务构建统一的认证授权入口_spring cloud认证登录授权 globalfilter

46 阅读3分钟
      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.ipaddress:{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<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 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 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; }

}


### 测试验证


登录:  
 ![在这里插入图片描述](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/97b810a75cf04858997cc0cf26481b2a~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1770646801&x-signature=ee89%2FCrHXqjDMf9E19qmrm03WMw%3D)  
 获取当前登录用户信息:  
 ![image.png](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/e026a68112d64e2694dec27b095ec60f~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1770646801&x-signature=7aJOE1oksZenqWXaPuq0CD8pZRk%3D)  
 退出登录:  
 ![在这里插入图片描述](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/a27a7b067d9d4262ac09e369251f07d4~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1770646801&x-signature=DvGE4hzq%2BD7lomqud8KVlDLbsck%3D)



> 
> 本文内容到此结束了,  
>  如有收获欢迎点赞👍收藏💖关注✔️,您的鼓励是我最大的动力。  
>  如有错误❌疑问💬欢迎各位指出。  
>  **主页**:[共饮一杯无的博客汇总👨‍💻](https://gitee.com/vip204888)
> 
> 
> **保持热爱,奔赴下一场山海**。🏃🏃🏃
> 
> 
> 



![img](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/58e7466df6904b64a9542029f44fdff5~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1770646801&x-signature=Ta0gj92qHfp39vqZ1Nj6IUasCTY%3D)
![img](https://p9-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/9d0e4e842c1c4c3e8eee636363edc6f7~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5py65Zmo5a2m5Lmg5LmL5b-DQUk=:q75.awebp?rk3s=f64ab15b&x-expires=1770646801&x-signature=MODjEKy8FnSlMzvvicr4Q40SR7U%3D)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://gitee.com/vip204888)**