207
207
import org .springframework .security .web .server .util .matcher .ServerWebExchangeMatchers ;
208
208
import org .springframework .util .Assert ;
209
209
import org .springframework .util .ClassUtils ;
210
+ import org .springframework .util .StringUtils ;
210
211
import org .springframework .web .cors .reactive .CorsConfigurationSource ;
211
212
import org .springframework .web .cors .reactive .CorsProcessor ;
212
213
import org .springframework .web .cors .reactive .CorsWebFilter ;
@@ -2958,7 +2959,8 @@ protected void configure(ServerHttpSecurity http) {
2958
2959
if (http .authenticationEntryPoint != null ) {
2959
2960
return ;
2960
2961
}
2961
- if (http .formLogin != null && http .formLogin .isEntryPointExplicit ) {
2962
+ if (http .formLogin != null && http .formLogin .isEntryPointExplicit
2963
+ || http .oauth2Login != null && StringUtils .hasText (http .oauth2Login .loginPage )) {
2962
2964
return ;
2963
2965
}
2964
2966
LoginPageGeneratingWebFilter loginPage = null ;
@@ -4135,6 +4137,8 @@ public final class OAuth2LoginSpec {
4135
4137
4136
4138
private ServerAuthenticationFailureHandler authenticationFailureHandler ;
4137
4139
4140
+ private String loginPage ;
4141
+
4138
4142
private OAuth2LoginSpec () {
4139
4143
}
4140
4144
@@ -4364,6 +4368,19 @@ private ServerWebExchangeMatcher getAuthenticationMatcher() {
4364
4368
return this .authenticationMatcher ;
4365
4369
}
4366
4370
4371
+ /**
4372
+ * Specifies the URL to send users to if login is required. A default login page
4373
+ * will be generated when this attribute is not specified.
4374
+ * @param loginPage the URL to send users to if login is required
4375
+ * @return the {@link OAuth2LoginSpec} for further configuration
4376
+ * @since 6.4
4377
+ */
4378
+ public OAuth2LoginSpec loginPage (String loginPage ) {
4379
+ Assert .hasText (loginPage , "loginPage cannot be empty" );
4380
+ this .loginPage = loginPage ;
4381
+ return this ;
4382
+ }
4383
+
4367
4384
/**
4368
4385
* Allows method chaining to continue configuring the {@link ServerHttpSecurity}
4369
4386
* @return the {@link ServerHttpSecurity} to continue configuring
@@ -4410,12 +4427,6 @@ protected void configure(ServerHttpSecurity http) {
4410
4427
}
4411
4428
4412
4429
private void setDefaultEntryPoints (ServerHttpSecurity http ) {
4413
- String defaultLoginPage = "/login" ;
4414
- Map <String , String > urlToText = http .oauth2Login .getLinks ();
4415
- String providerLoginPage = null ;
4416
- if (urlToText .size () == 1 ) {
4417
- providerLoginPage = urlToText .keySet ().iterator ().next ();
4418
- }
4419
4430
MediaTypeServerWebExchangeMatcher htmlMatcher = new MediaTypeServerWebExchangeMatcher (
4420
4431
MediaType .APPLICATION_XHTML_XML , new MediaType ("image" , "*" ), MediaType .TEXT_HTML ,
4421
4432
MediaType .TEXT_PLAIN );
@@ -4429,22 +4440,34 @@ MediaType.APPLICATION_XHTML_XML, new MediaType("image", "*"), MediaType.TEXT_HTM
4429
4440
ServerWebExchangeMatcher notXhrMatcher = new NegatedServerWebExchangeMatcher (xhrMatcher );
4430
4441
ServerWebExchangeMatcher defaultEntryPointMatcher = new AndServerWebExchangeMatcher (notXhrMatcher ,
4431
4442
htmlMatcher );
4432
- if (providerLoginPage != null ) {
4433
- ServerWebExchangeMatcher loginPageMatcher = new PathPatternParserServerWebExchangeMatcher (
4434
- defaultLoginPage );
4435
- ServerWebExchangeMatcher faviconMatcher = new PathPatternParserServerWebExchangeMatcher ("/favicon.ico" );
4436
- ServerWebExchangeMatcher defaultLoginPageMatcher = new AndServerWebExchangeMatcher (
4437
- new OrServerWebExchangeMatcher (loginPageMatcher , faviconMatcher ), defaultEntryPointMatcher );
4438
-
4439
- ServerWebExchangeMatcher matcher = new AndServerWebExchangeMatcher (notXhrMatcher ,
4440
- new NegatedServerWebExchangeMatcher (defaultLoginPageMatcher ));
4441
- RedirectServerAuthenticationEntryPoint entryPoint = new RedirectServerAuthenticationEntryPoint (
4442
- providerLoginPage );
4443
- entryPoint .setRequestCache (http .requestCache .requestCache );
4444
- http .defaultEntryPoints .add (new DelegateEntry (matcher , entryPoint ));
4443
+ String loginPage = "/login" ;
4444
+ if (StringUtils .hasText (this .loginPage )) {
4445
+ loginPage = this .loginPage ;
4446
+ }
4447
+ else {
4448
+ Map <String , String > urlToText = http .oauth2Login .getLinks ();
4449
+ String providerLoginPage = null ;
4450
+ if (urlToText .size () == 1 ) {
4451
+ providerLoginPage = urlToText .keySet ().iterator ().next ();
4452
+ }
4453
+ if (providerLoginPage != null ) {
4454
+ ServerWebExchangeMatcher loginPageMatcher = new PathPatternParserServerWebExchangeMatcher (
4455
+ loginPage );
4456
+ ServerWebExchangeMatcher faviconMatcher = new PathPatternParserServerWebExchangeMatcher (
4457
+ "/favicon.ico" );
4458
+ ServerWebExchangeMatcher defaultLoginPageMatcher = new AndServerWebExchangeMatcher (
4459
+ new OrServerWebExchangeMatcher (loginPageMatcher , faviconMatcher ), defaultEntryPointMatcher );
4460
+
4461
+ ServerWebExchangeMatcher matcher = new AndServerWebExchangeMatcher (notXhrMatcher ,
4462
+ new NegatedServerWebExchangeMatcher (defaultLoginPageMatcher ));
4463
+ RedirectServerAuthenticationEntryPoint entryPoint = new RedirectServerAuthenticationEntryPoint (
4464
+ providerLoginPage );
4465
+ entryPoint .setRequestCache (http .requestCache .requestCache );
4466
+ http .defaultEntryPoints .add (new DelegateEntry (matcher , entryPoint ));
4467
+ }
4445
4468
}
4446
4469
RedirectServerAuthenticationEntryPoint defaultEntryPoint = new RedirectServerAuthenticationEntryPoint (
4447
- defaultLoginPage );
4470
+ loginPage );
4448
4471
defaultEntryPoint .setRequestCache (http .requestCache .requestCache );
4449
4472
http .defaultEntryPoints .add (new DelegateEntry (defaultEntryPointMatcher , defaultEntryPoint ));
4450
4473
}
0 commit comments