当前位置:网站首页>第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 中取出。
边栏推荐
- Online yaml to CSV tool
- Comparison of parameters between TVs tube and zener diode
- STM32__ 06 - single channel ADC
- Objective C message dispatch mechanism
- Redis高可用——主从复制、哨兵模式、集群
- GFS distributed file system
- MySQL delete uniqueness constraint unique
- Zhongjun group launched electronic contracts to accelerate the digital development of real estate enterprises
- SpreadJS 15.1 CN 与 SpreadJS 15.1 EN
- Problem solving win10 quickly open ipynb file
猜你喜欢
Comparison of parameters between TVs tube and zener diode
The use of El cascader and the solution of error reporting
保研笔记二 软件工程与计算卷二(13-16章)
"14th five year plan": emphasis on the promotion of electronic contracts, electronic signatures and other applications
MySQL delete uniqueness constraint unique
orgchart. JS organization chart, presenting structural data in an elegant way
CIS benchmark tool Kube bench
20220703 week race: number of people who know the secret - dynamic rules (problem solution)
STM32__ 06 - single channel ADC
98. 验证二叉搜索树 ●●
随机推荐
【LeetCode】5. Valid Palindrome·有效回文
XML配置文件(DTD详细讲解)
21. PWM application programming
424. The longest repeated character after replacement ●●
Senparc.Weixin.Sample.MP源码剖析
China Jinmao online electronic signature, accelerating the digitization of real estate business
20220703 week race: number of people who know the secret - dynamic rules (problem solution)
Make a short video clip number of we media film and television. Where can I download the material?
Rsync remote synchronization
Use mapper: --- tkmapper
In C#, why can't I modify the member of a value type instance in a foreach loop?
Live tiktok shop 2022 latest gameplay card slot overseas live e-commerce new traffic
用列表初始化你的vector&&initializer_list简介
【GYM 102832H】【模板】Combination Lock(二分图博弈)
Laser slam learning record
Fiddler Everywhere 3.2.1 Crack
Opencvsharp (C openCV) shape detection and recognition (with source code)
How to enable relationship view in phpMyAdmin - how to enable relationship view in phpMyAdmin
Spécifications techniques et lignes directrices pour la sélection des tubes TVS et ESD - Recommandation de jialichuang
TVS管和ESD管的技術指標和選型指南-嘉立創推薦