当前位置:网站首页>第16章 OAuth2AuthorizationRequestRedirectWebFilter源码解析
第16章 OAuth2AuthorizationRequestRedirectWebFilter源码解析
2022-07-05 23:40:00 【buffeer】
OAuth2AuthorizationRequestRedirectWebFilter 过滤器是用来重定向到第三方授权服务器。
1.概览
OAuth2AuthorizationRequestRedirectWebFilter 过滤器依赖类:
- ServerAuthorizationRequestRepository:存储 AuthorizationRequest 对象
- ServerOAuth2AuthorizationRequestResolver:拦截指定的请求并解析
OAuth2AuthorizationRequestRedirectWebFilter 依赖的两个类都可以自定义配置。如果没有自定义配置,那么就会使用默认的。
2.初始化
SeverHttpSecurity 的方法 configure 内会创建 OAuth2AuthorizationRequestRedirectWebFilter 过滤器。先来看一下它如何被创建的,源码如下所示。
protected void configure(ServerHttpSecurity http) {
OAuth2AuthorizationRequestRedirectWebFilter oauthRedirectFilter = this.getRedirectWebFilter();
ServerAuthorizationRequestRepository<OAuth2AuthorizationRequest> authorizationRequestRepository = this.getAuthorizationRequestRepository();
oauthRedirectFilter.setAuthorizationRequestRepository(authorizationRequestRepository);
oauthRedirectFilter.setRequestCache(http.requestCache.requestCache);
}
创建 OAuth2AuthorizationRequestRedirectWebFilter 过滤器时,如果配置自定义的 authorizationRequestResolver ,则使用它拦截指定请求并解析;否则默认的解析器,拦截请求路径为 /oauth2/authorization。
private OAuth2AuthorizationRequestRedirectWebFilter getRedirectWebFilter() {
// 如果配置了自定义的 authorizationRequestResolver。使用自定义的 authorizationRequestResolver
// 否则使用默认的 DefaultServerOAuth2AuthorizationRequestResolver
return this.authorizationRequestResolver != null ? new OAuth2AuthorizationRequestRedirectWebFilter(this.authorizationRequestResolver) : new OAuth2AuthorizationRequestRedirectWebFilter(this.getClientRegistrationRepository());
}
创建 ServerAuthorizationRequestRepository 时,如果配置了自定义的 authorizationRequestRepository ,则使用自定义的;否则使用默认的基于 Session 存储,把 OAuth2AuthorizationRequest 对象存储在 Session 中。
private ServerAuthorizationRequestRepository<OAuth2AuthorizationRequest> getAuthorizationRequestRepository() {
if (this.authorizationRequestRepository == null) {
this.authorizationRequestRepository = new WebSessionOAuth2ServerAuthorizationRequestRepository();
}
return this.authorizationRequestRepository;
}
3.过滤器核心源码分析
OAuth2AuthorizationRequestRedirectWebFilter 过滤器的核心功能就是:拦截请求并重定向到第三方授权服务器。什么请求会被拦截、如何重定向?带着这些问题一起来看看源码。
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
return this.authorizationRequestResolver.resolve(exchange)
.switchIfEmpty(chain.filter(exchange).then(Mono.empty()))
.onErrorResume(ClientAuthorizationRequiredException.class,
(ex) -> this.requestCache.saveRequest(exchange).then(
this.authorizationRequestResolver.resolve(exchange, ex.getClientRegistrationId()))
)
.flatMap((clientRegistration) -> sendRedirectForAuthorization(exchange, clientRegistration));
}
private Mono<Void> sendRedirectForAuthorization(ServerWebExchange exchange,
OAuth2AuthorizationRequest authorizationRequest) {
return Mono.defer(() -> {
Mono<Void> saveAuthorizationRequest = Mono.empty();
if (AuthorizationGrantType.AUTHORIZATION_CODE.equals(authorizationRequest.getGrantType())) {
// 存储到 Session 中
saveAuthorizationRequest = this.authorizationRequestRepository
.saveAuthorizationRequest(authorizationRequest, exchange);
}
// 授权地址
URI redirectUri = UriComponentsBuilder.fromUriString(authorizationRequest.getAuthorizationRequestUri())
.build(true)
.toUri();
// 重定向
return saveAuthorizationRequest
.then(this.authorizationRedirectStrategy.sendRedirect(exchange, redirectUri));
});
}
4.默认的 authorizationRequestResolver
默认的 authorizationRequestResolver 的实现类是 DefaultServerOAuth2AuthorizationRequestResolver。它默认是拦截请求 /oauth2/authorization
public class DefaultServerOAuth2AuthorizationRequestResolver implements ServerOAuth2AuthorizationRequestResolver {
public static final String DEFAULT_REGISTRATION_ID_URI_VARIABLE_NAME = "registrationId";
public static final String DEFAULT_AUTHORIZATION_REQUEST_PATTERN = "/oauth2/authorization/{"
+ DEFAULT_REGISTRATION_ID_URI_VARIABLE_NAME + "}";
public DefaultServerOAuth2AuthorizationRequestResolver(
ReactiveClientRegistrationRepository clientRegistrationRepository) {
// path 匹配器
this(clientRegistrationRepository,
new PathPatternParserServerWebExchangeMatcher(DEFAULT_AUTHORIZATION_REQUEST_PATTERN));
}
}
DefaultServerOAuth2AuthorizationRequestResolver 的功能返回 OAuth2AuthorizationRequest(授权请求信息),它表示授权请求。DefaultServerOAuth2AuthorizationRequestResolver 是如何创建它的呢?如下源码所示:
private OAuth2AuthorizationRequest authorizationRequest(ServerWebExchange exchange,
ClientRegistration clientRegistration) {
// 回调url。 application.yml配置对应申请应用配置回调url
String redirectUriStr = expandRedirectUri(exchange.getRequest(), clientRegistration);
Map<String, Object> attributes = new HashMap<>();
attributes.put(OAuth2ParameterNames.REGISTRATION_ID, clientRegistration.getRegistrationId());
OAuth2AuthorizationRequest.Builder builder = getBuilder(clientRegistration, attributes);
builder.clientId(clientRegistration.getClientId())
.authorizationUri(clientRegistration.getProviderDetails().getAuthorizationUri())
.redirectUri(redirectUriStr)
.scopes(clientRegistration.getScopes())
// 防止请求被篡改
.state(this.stateGenerator.generateKey())
.attributes(attributes);
this.authorizationRequestCustomizer.accept(builder);
return builder.build();
}
方法 expandRedirectUri 支持Uri变量替换。例如在 application.yml 配置
spring:
security:
oauth2:
client:
registration:
google:
clientId: "xxxx"
clientSecret: "xxxx"
redirectUri: "{baseUrl}/api/oauth2/code/{registrationId}"
5.默认的 authorizationRequestRepository
默认的 authorizationRequestResolver 的实现类 WebSessionOAuth2ServerAuthorizationRequestRepository 基于 Session 存储。它会把 OAuth2AuthorizationRequest 存储到 Session 中,方便后续请求从 Session 中取出。
边栏推荐
- Biased sample variance, unbiased sample variance
- How to insert data into MySQL database- How can I insert data into a MySQL database?
- 做自媒体影视短视频剪辑号,在哪儿下载素材?
- 帶外和帶內的區別
- How to rotate the synchronized / refreshed icon (EL icon refresh)
- Laser slam learning record
- Rasa 3.x 学习系列-Rasa X 社区版(免费版) 更改
- 微信小程序---WXML 模板语法(附带笔记文档)
- 零犀科技携手集智俱乐部:“因果派”论坛成功举办,“因果革命”带来下一代可信AI
- 如何提升口才
猜你喜欢
Spécifications techniques et lignes directrices pour la sélection des tubes TVS et ESD - Recommandation de jialichuang
Do you regret becoming a programmer?
Fiddler Everywhere 3.2.1 Crack
教你在HbuilderX上使用模拟器运行uni-app,良心教学!!!
698. 划分为k个相等的子集 ●●
Rasa 3. X learning series -rasa 3.2.1 new release
Breadth first search open turntable lock
openssl-1.0.2k版本升级openssl-1.1.1p
Technical specifications and model selection guidelines for TVs tubes and ESD tubes - recommended by jialichuang
跟着CTF-wiki学pwn——ret2libc1
随机推荐
【LeetCode】5. Valid Palindrome·有效回文
The PostgreSQL column reference 'ID' is ambiguous - PostgreSQL column reference'id'is ambiguous
Cwaitabletimer timer, used to create timer object access
C# 反射与Type
18.(arcgis api for js篇)arcgis api for js点采集(SketchViewModel)
MySQL delete uniqueness constraint unique
Technical specifications and model selection guidelines for TVs tubes and ESD tubes - recommended by jialichuang
Idea connects to MySQL, and it is convenient to paste the URL of the configuration file directly
shardingsphere源码解析
【GYM 102832H】【模板】Combination Lock(二分图博弈)
15 MySQL-存储过程与函数
[classical control theory] summary of automatic control experiment
idea 连接mysql ,直接贴配置文件的url 比较方便
Convert Chinese into pinyin
动态规划 之 打家劫舍
Neural structured learning - Part 2: training with natural graphs
多普勒效應(多普勒頻移)
TS type declaration
Problem solving win10 quickly open ipynb file
Effet Doppler (déplacement de fréquence Doppler)