SpringCloud Alibaba微服务实战十四 - SpringCloud Gateway集成Oauth2

//根据access_token从数据库获取不到OAuth2AccessToken

if(oAuth2AccessToken == null){

return Mono.error(new InvalidTokenException(“invalid access token,please check”));

}else if(oAuth2AccessToken.isExpired()){

return Mono.error(new InvalidTokenException(“access token has expired,please reacquire token”));

}

OAuth2Authentication oAuth2Authentication =this.tokenStore.readAuthentication(accessToken);

if(oAuth2Authentication == null){

return Mono.error(new InvalidTokenException(“Access Token 无效!”));

}else {

return Mono.just(oAuth2Authentication);

}

})).cast(Authentication.class);

}

}

网关层的安全配置

@Configuration

public class SecurityConfig {

private static final String MAX_AGE = “18000L”;

@Autowired

private DataSource dataSource;

@Autowired

private AccessManager accessManager;

/**

  • 跨域配置

*/

public WebFilter corsFilter() {

return (ServerWebExchange ctx, WebFilterChain chain) -> {

ServerHttpRequest request = ctx.getRequest();

if (CorsUtils.isCorsRequest(request)) {

HttpHeaders requestHeaders = request.getHeaders();

ServerHttpResponse response = ctx.getResponse();

HttpMethod requestMethod = requestHeaders.getAccessControlRequestMethod();

HttpHeaders headers = response.getHeaders();

headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, requestHeaders.getOrigin());

headers.addAll(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, requestHeaders.getAccessControlRequestHeaders());

if (requestMethod != null) {

headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, requestMethod.name());

}

headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, “true”);

headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, “*”);

headers.add(HttpHeaders.ACCESS_CONTROL_MAX_AGE, MAX_AGE);

if (request.getMethod() == HttpMethod.OPTIONS) {

response.setStatusCode(HttpStatus.OK);

return Mono.empty();

}

}

return chain.filter(ctx);

};

}

@Bean

SecurityWebFilterChain webFluxSecurityFilterChain(ServerHttpSecurity http) throws Exception{

//token管理器

ReactiveAuthenticationManager tokenAuthenticationManager = new ReactiveJdbcAuthenticationManager(new JdbcTokenStore(dataSource));

//认证过滤器

AuthenticationWebFilter authenticationWebFilter = new AuthenticationWebFilter(tokenAuthenticationManager);

authenticationWebFilter.setServerAuthenticationConverter(new ServerBearerTokenAuthenticationConverter());

http

.httpBasic().disable()

.csrf().disable()

.authorizeExchange()

.pathMatchers(HttpMethod.OPTIONS).permitAll()

.anyExchange().access(accessManager)

.and()

// 跨域过滤器

.addFilterAt(corsFilter(), SecurityWebFiltersOrder.CORS)

//oauth2认证过滤器

.addFilterAt(authenticationWebFilter, SecurityWebFiltersOrder.AUTHENTICATION);

return http.build();

}

}

这个类是SpringCloug Gateway 与 Oauth2整合的关键,通过构建认证过滤器 AuthenticationWebFilter 完成Oauth2.0的token校验。

AuthenticationWebFilter 通过我们自定义的 ReactiveJdbcAuthenticationManager 完成token校验。

我们在这里还加入了CORS过滤器,以及权限管理器 AccessManager

权限管理器

@Slf4j

@Component

public class AccessManager implements ReactiveAuthorizationManager {

private Set permitAll = new ConcurrentHashSet<>();

private static final AntPathMatcher antPathMatcher = new AntPathMatcher();

public AccessManager (){

permitAll.add(“/”);

permitAll.add(“/error”);

permitAll.add(“/favicon.ico”);

permitAll.add(“//v2/api-docs/”);

permitAll.add(“//swagger-resources/”);

permitAll.add(“/webjars/**”);

permitAll.add(“/doc.html”);

permitAll.add(“/swagger-ui.html”);

permitAll.add(“//oauth/”);

permitAll.add(“/**/current/get”);

}

/**

  • 实现权限验证判断

*/

@Override

public Mono check(Mono authenticationMono, AuthorizationContext authorizationContext) {

ServerWebExchange exchange = authorizationContext.getExchange();

//请求资源

String requestPath = exchange.getRequest().getURI().getPath();

// 是否直接放行

if (permitAll(requestPath)) {

return Mono.just(new AuthorizationDecision(true));

}

return authenticationMono.map(auth -> {

return new AuthorizationDecision(checkAuthorities(exchange, auth, requestPath));

}).defaultIfEmpty(new AuthorizationDecision(false));

}

/**

  • 校验是否属于静态资源

  • @param requestPath 请求路径

  • @return

*/

private boolean permitAll(String requestPath) {

return permitAll.stream()

.filter(r -> antPathMatcher.match(r, requestPath)).findFirst().isPresent();

}

//权限校验

private boolean checkAuthorities(ServerWebExchange exchange, Authentication auth, String requestPath) {

if(auth instanceof OAuth2Authentication){

OAuth2Authentication athentication = (OAuth2Authentication) auth;

String clientId = athentication.getOAuth2Request().getClientId();

log.info(“clientId is {}”,clientId);

}

Object principal = auth.getPrincipal();

log.info(“用户信息:{}”,principal.toString());

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
img

望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**
[外链图片转存中…(img-1t4lxxmU-1710843467750)]
[外链图片转存中…(img-bJAKNzmS-1710843467751)]
[外链图片转存中…(img-ABIjOJCH-1710843467751)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
[外链图片转存中…(img-gKGgMrBj-1710843467752)]

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值