mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-05-31 17:22:13 +00:00
Allow form login when single OAuth2 Provider is configured
Closes gh-6802
This commit is contained in:
parent
d18291676f
commit
a061191bd2
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2021 the original author or authors.
|
* Copyright 2002-2022 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.springframework.security.config.annotation.web.configurers.oauth2.client;
|
package org.springframework.security.config.annotation.web.configurers.oauth2.client;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -73,12 +74,14 @@ import org.springframework.security.web.authentication.ui.DefaultLoginPageGenera
|
|||||||
import org.springframework.security.web.savedrequest.RequestCache;
|
import org.springframework.security.web.savedrequest.RequestCache;
|
||||||
import org.springframework.security.web.util.matcher.AndRequestMatcher;
|
import org.springframework.security.web.util.matcher.AndRequestMatcher;
|
||||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||||
|
import org.springframework.security.web.util.matcher.AnyRequestMatcher;
|
||||||
import org.springframework.security.web.util.matcher.NegatedRequestMatcher;
|
import org.springframework.security.web.util.matcher.NegatedRequestMatcher;
|
||||||
import org.springframework.security.web.util.matcher.OrRequestMatcher;
|
import org.springframework.security.web.util.matcher.OrRequestMatcher;
|
||||||
import org.springframework.security.web.util.matcher.RequestHeaderRequestMatcher;
|
import org.springframework.security.web.util.matcher.RequestHeaderRequestMatcher;
|
||||||
import org.springframework.security.web.util.matcher.RequestMatcher;
|
import org.springframework.security.web.util.matcher.RequestMatcher;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
|
import org.springframework.util.ReflectionUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An {@link AbstractHttpConfigurer} for OAuth 2.0 Login, which leverages the OAuth 2.0
|
* An {@link AbstractHttpConfigurer} for OAuth 2.0 Login, which leverages the OAuth 2.0
|
||||||
@ -503,14 +506,28 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>>
|
|||||||
new OrRequestMatcher(loginPageMatcher, faviconMatcher), defaultEntryPointMatcher);
|
new OrRequestMatcher(loginPageMatcher, faviconMatcher), defaultEntryPointMatcher);
|
||||||
RequestMatcher notXRequestedWith = new NegatedRequestMatcher(
|
RequestMatcher notXRequestedWith = new NegatedRequestMatcher(
|
||||||
new RequestHeaderRequestMatcher("X-Requested-With", "XMLHttpRequest"));
|
new RequestHeaderRequestMatcher("X-Requested-With", "XMLHttpRequest"));
|
||||||
|
RequestMatcher formLoginNotEnabled = getFormLoginNotEnabledRequestMatcher(http);
|
||||||
LinkedHashMap<RequestMatcher, AuthenticationEntryPoint> entryPoints = new LinkedHashMap<>();
|
LinkedHashMap<RequestMatcher, AuthenticationEntryPoint> entryPoints = new LinkedHashMap<>();
|
||||||
entryPoints.put(new AndRequestMatcher(notXRequestedWith, new NegatedRequestMatcher(defaultLoginPageMatcher)),
|
entryPoints.put(new AndRequestMatcher(notXRequestedWith, new NegatedRequestMatcher(defaultLoginPageMatcher),
|
||||||
new LoginUrlAuthenticationEntryPoint(providerLoginPage));
|
formLoginNotEnabled), new LoginUrlAuthenticationEntryPoint(providerLoginPage));
|
||||||
DelegatingAuthenticationEntryPoint loginEntryPoint = new DelegatingAuthenticationEntryPoint(entryPoints);
|
DelegatingAuthenticationEntryPoint loginEntryPoint = new DelegatingAuthenticationEntryPoint(entryPoints);
|
||||||
loginEntryPoint.setDefaultEntryPoint(this.getAuthenticationEntryPoint());
|
loginEntryPoint.setDefaultEntryPoint(this.getAuthenticationEntryPoint());
|
||||||
return loginEntryPoint;
|
return loginEntryPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private RequestMatcher getFormLoginNotEnabledRequestMatcher(B http) {
|
||||||
|
DefaultLoginPageGeneratingFilter defaultLoginPageGeneratingFilter = http
|
||||||
|
.getSharedObject(DefaultLoginPageGeneratingFilter.class);
|
||||||
|
Field formLoginEnabledField = (defaultLoginPageGeneratingFilter != null)
|
||||||
|
? ReflectionUtils.findField(DefaultLoginPageGeneratingFilter.class, "formLoginEnabled") : null;
|
||||||
|
if (formLoginEnabledField != null) {
|
||||||
|
ReflectionUtils.makeAccessible(formLoginEnabledField);
|
||||||
|
return (request) -> Boolean.FALSE
|
||||||
|
.equals(ReflectionUtils.getField(formLoginEnabledField, defaultLoginPageGeneratingFilter));
|
||||||
|
}
|
||||||
|
return AnyRequestMatcher.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration options for the Authorization Server's Authorization Endpoint.
|
* Configuration options for the Authorization Server's Authorization Endpoint.
|
||||||
*/
|
*/
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2021 the original author or authors.
|
* Copyright 2002-2022 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -368,6 +368,17 @@ public class OAuth2LoginConfigurerTests {
|
|||||||
assertThat(this.response.getRedirectedUrl()).matches("http://localhost/oauth2/authorization/google");
|
assertThat(this.response.getRedirectedUrl()).matches("http://localhost/oauth2/authorization/google");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// gh-6802
|
||||||
|
@Test
|
||||||
|
public void oauth2LoginWithOneClientConfiguredAndFormLoginThenRedirectDefaultLoginPage() throws Exception {
|
||||||
|
loadConfig(OAuth2LoginConfigFormLogin.class);
|
||||||
|
String requestUri = "/";
|
||||||
|
this.request = new MockHttpServletRequest("GET", requestUri);
|
||||||
|
this.request.setServletPath(requestUri);
|
||||||
|
this.springSecurityFilterChain.doFilter(this.request, this.response, this.filterChain);
|
||||||
|
assertThat(this.response.getRedirectedUrl()).matches("http://localhost/login");
|
||||||
|
}
|
||||||
|
|
||||||
// gh-5347
|
// gh-5347
|
||||||
@Test
|
@Test
|
||||||
public void oauth2LoginWithOneClientConfiguredAndRequestFaviconNotAuthenticatedThenRedirectDefaultLoginPage()
|
public void oauth2LoginWithOneClientConfiguredAndRequestFaviconNotAuthenticatedThenRedirectDefaultLoginPage()
|
||||||
@ -642,6 +653,26 @@ public class OAuth2LoginConfigurerTests {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@EnableWebSecurity
|
||||||
|
static class OAuth2LoginConfigFormLogin extends CommonWebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
|
private final InMemoryClientRegistrationRepository clientRegistrationRepository = new InMemoryClientRegistrationRepository(
|
||||||
|
GOOGLE_CLIENT_REGISTRATION);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
|
// @formatter:off
|
||||||
|
http
|
||||||
|
.oauth2Login()
|
||||||
|
.clientRegistrationRepository(this.clientRegistrationRepository)
|
||||||
|
.and()
|
||||||
|
.formLogin();
|
||||||
|
// @formatter:on
|
||||||
|
super.configure(http);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
static class OAuth2LoginInLambdaConfig extends CommonLambdaWebSecurityConfigurerAdapter
|
static class OAuth2LoginInLambdaConfig extends CommonLambdaWebSecurityConfigurerAdapter
|
||||||
implements ApplicationListener<AuthenticationSuccessEvent> {
|
implements ApplicationListener<AuthenticationSuccessEvent> {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user