//根据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开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**
[外链图片转存中…(img-1t4lxxmU-1710843467750)]
[外链图片转存中…(img-bJAKNzmS-1710843467751)]
[外链图片转存中…(img-ABIjOJCH-1710843467751)]
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
[外链图片转存中…(img-gKGgMrBj-1710843467752)]