当前位置:网站首页>第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 中取出。
边栏推荐
- C file and folder operation
- GFS分布式文件系統
- 如何让同步/刷新的图标(el-icon-refresh)旋转起来
- Huawei simulator ENSP - hcip - MPLS experiment
- Rsync remote synchronization
- 帶外和帶內的區別
- Bao Yan notes II software engineering and calculation volume II (Chapter 13-16)
- 开源crm客户关系统管理系统源码,免费分享
- 4 points tell you the advantages of the combination of real-time chat and chat robots
- My colleagues quietly told me that flying Book notification can still play like this
猜你喜欢

C# 反射与Type

Spire.PDF for NET 8.7.2

Initialize your vector & initializer with a list_ List introduction

保研笔记一 软件工程与计算卷二(1-7章)

Breadth first search open turntable lock

Problem solving win10 quickly open ipynb file

用列錶初始化你的vector&&initializer_list簡介

Bao Yan notebook IV software engineering and calculation volume II (Chapter 8-12)

C reflection and type

Brushless drive design -- on MOS drive circuit
随机推荐
Spire Office 7.5.4 for NET
424. The longest repeated character after replacement ●●
PADS ROUTER 使用技巧小记
CIS基准测试工具kube-bench使用
总结了 800多个 Kubectl 别名,再也不怕记不住命令了!
698. 划分为k个相等的子集 ●●
Comparison between webgl and webgpu [3] - vertex buffer
转:未来,这样的组织才能扛住风险
Idea connects to MySQL, and it is convenient to paste the URL of the configuration file directly
698. Divided into k equal subsets ●●
Rasa 3. X learning series -rasa 3.2.1 new release
Initialiser votre vecteur & initialisateur avec une liste Introduction à la Liste
C# 文件与文件夹操作
Tips for using pads router
保研笔记四 软件工程与计算卷二(8-12章)
Senparc.Weixin.Sample.MP源码剖析
[Yu Yue education] NC machining technology reference materials of Shaanxi University of science and technology
15 MySQL stored procedures and functions
Latex multiple linebreaks
UVA11294-Wedding(2-SAT)