当前位置:网站首页>第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 中取出。
边栏推荐
- CIS基准测试工具kube-bench使用
- Spire Office 7.5.4 for NET
- 如何提升口才
- [day39 literature extensive reading] a Bayesian perspective on magnetic estimation
- Comparison between webgl and webgpu [3] - vertex buffer
- "14th five year plan": emphasis on the promotion of electronic contracts, electronic signatures and other applications
- Spire Office 7.5.4 for NET
- My colleagues quietly told me that flying Book notification can still play like this
- How to get all the values stored in localstorage
- How to improve eloquence
猜你喜欢

Tips for using pads router

开源crm客户关系统管理系统源码,免费分享

Switching power supply buck circuit CCM and DCM working mode

【LeetCode】5. Valid Palindrome·有效回文

The use of El cascader and the solution of error reporting

Fiddler Everywhere 3.2.1 Crack

妙才周刊 - 8

Rasa 3.x 学习系列-Rasa X 社区版(免费版) 更改

orgchart. JS organization chart, presenting structural data in an elegant way

Spire Office 7.5.4 for NET
随机推荐
White hat talks about web security after reading 2
MySQL replace primary key delete primary key add primary key
多普勒效應(多普勒頻移)
Hcip course notes-16 VLAN, three-tier architecture, MPLS virtual private line configuration
SpreadJS 15.1 CN 与 SpreadJS 15.1 EN
Problem solving win10 quickly open ipynb file
In C#, why can't I modify the member of a value type instance in a foreach loop?
Switching power supply buck circuit CCM and DCM working mode
4 points tell you the advantages of the combination of real-time chat and chat robots
How to rotate the synchronized / refreshed icon (EL icon refresh)
rsync远程同步
【luogu P3295】萌萌哒(并查集)(倍增)
上门预约服务类的App功能详解
转:未来,这样的组织才能扛住风险
Spire.PDF for NET 8.7.2
Initialiser votre vecteur & initialisateur avec une liste Introduction à la Liste
Spire Office 7.5.4 for NET
Brushless drive design -- on MOS drive circuit
openssl-1.0.2k版本升级openssl-1.1.1p
妙才周刊 - 8