Add AuthenticationManager to HttpSecurity

Closes gh-10040
This commit is contained in:
Eleftheria Stein
2021-07-07 15:44:42 +02:00
parent 88a3f5ad39
commit 585788ad0a
6 changed files with 311 additions and 3 deletions

View File

@@ -0,0 +1,119 @@
/*
* Copyright 2012-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.security.config.annotation.web.builders;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.test.SpringTestRule;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.test.web.servlet.MockMvc;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.springframework.security.config.Customizer.withDefaults;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
public class HttpSecurityAuthenticationManagerTests {
@Autowired
MockMvc mvc;
@Rule
public final SpringTestRule spring = new SpringTestRule();
@Test
public void authenticationManagerWhenConfiguredThenUsed() throws Exception {
this.spring.register(AuthenticationManagerConfig.class).autowire();
given(AuthenticationManagerConfig.AUTHENTICATION_MANAGER.authenticate(any()))
.willReturn(new TestingAuthenticationToken("user", "test", "ROLE_USER"));
this.mvc.perform(get("/").with(httpBasic("user", "test")));
verify(AuthenticationManagerConfig.AUTHENTICATION_MANAGER).authenticate(any());
}
@Test
public void authenticationManagerWhenBuilderAndAuthenticationManagerConfiguredThenBuilderIgnored()
throws Exception {
this.spring.register(AuthenticationManagerBuilderConfig.class).autowire();
given(AuthenticationManagerBuilderConfig.AUTHENTICATION_MANAGER.authenticate(any()))
.willReturn(new TestingAuthenticationToken("user", "test", "ROLE_USER"));
this.mvc.perform(get("/").with(httpBasic("user", "test")));
verify(AuthenticationManagerBuilderConfig.AUTHENTICATION_MANAGER).authenticate(any());
verifyNoInteractions(AuthenticationManagerBuilderConfig.USER_DETAILS_SERVICE);
}
@EnableWebSecurity
static class AuthenticationManagerConfig extends WebSecurityConfigurerAdapter {
static final AuthenticationManager AUTHENTICATION_MANAGER = mock(AuthenticationManager.class);
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests((authz) -> authz
.anyRequest().authenticated()
)
.httpBasic(withDefaults())
.authenticationManager(AUTHENTICATION_MANAGER);
// @formatter:on
}
}
@EnableWebSecurity
static class AuthenticationManagerBuilderConfig extends WebSecurityConfigurerAdapter {
static final AuthenticationManager AUTHENTICATION_MANAGER = mock(AuthenticationManager.class);
static final UserDetailsService USER_DETAILS_SERVICE = mock(UserDetailsService.class);
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests((authz) -> authz
.anyRequest().authenticated()
)
.httpBasic(withDefaults())
.authenticationManager(AUTHENTICATION_MANAGER);
// @formatter:on
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(USER_DETAILS_SERVICE);
}
}
}

View File

@@ -996,6 +996,24 @@ public class OAuth2ResourceServerConfigurerTests {
verifyBean(AuthenticationProvider.class).authenticate(any(Authentication.class));
}
@Test
public void getWhenDefaultAndCustomJwtAuthenticationManagerThenCustomUsed() throws Exception {
this.spring.register(DefaultAndJwtAuthenticationManagerConfig.class, BasicController.class).autowire();
DefaultAndJwtAuthenticationManagerConfig config = this.spring.getContext()
.getBean(DefaultAndJwtAuthenticationManagerConfig.class);
AuthenticationManager defaultAuthenticationManager = config.defaultAuthenticationManager();
AuthenticationManager jwtAuthenticationManager = config.jwtAuthenticationManager();
given(defaultAuthenticationManager.authenticate(any()))
.willThrow(new RuntimeException("should not interact with default auth manager"));
given(jwtAuthenticationManager.authenticate(any())).willReturn(JWT_AUTHENTICATION_TOKEN);
// @formatter:off
this.mvc.perform(get("/authenticated").with(bearerToken("token")))
.andExpect(status().isOk())
.andExpect(content().string("mock-test-subject"));
// @formatter:on
verify(jwtAuthenticationManager).authenticate(any(Authentication.class));
}
@Test
public void getWhenIntrospectingThenOk() throws Exception {
this.spring.register(RestOperationsConfig.class, OpaqueTokenConfig.class, BasicController.class).autowire();
@@ -1054,6 +1072,24 @@ public class OAuth2ResourceServerConfigurerTests {
verifyBean(AuthenticationProvider.class).authenticate(any(Authentication.class));
}
@Test
public void getWhenDefaultAndCustomIntrospectionAuthenticationManagerThenCustomUsed() throws Exception {
this.spring.register(DefaultAndOpaqueTokenAuthenticationManagerConfig.class, BasicController.class).autowire();
DefaultAndOpaqueTokenAuthenticationManagerConfig config = this.spring.getContext()
.getBean(DefaultAndOpaqueTokenAuthenticationManagerConfig.class);
AuthenticationManager defaultAuthenticationManager = config.defaultAuthenticationManager();
AuthenticationManager opaqueTokenAuthenticationManager = config.opaqueTokenAuthenticationManager();
given(defaultAuthenticationManager.authenticate(any()))
.willThrow(new RuntimeException("should not interact with default auth manager"));
given(opaqueTokenAuthenticationManager.authenticate(any())).willReturn(INTROSPECTION_AUTHENTICATION_TOKEN);
// @formatter:off
this.mvc.perform(get("/authenticated").with(bearerToken("token")))
.andExpect(status().isOk())
.andExpect(content().string("mock-test-subject"));
// @formatter:on
verify(opaqueTokenAuthenticationManager).authenticate(any(Authentication.class));
}
@Test
public void getWhenCustomIntrospectionAuthenticationManagerInLambdaThenUsed() throws Exception {
this.spring.register(OpaqueTokenAuthenticationManagerInLambdaConfig.class, BasicController.class).autowire();
@@ -2017,6 +2053,39 @@ public class OAuth2ResourceServerConfigurerTests {
}
@EnableWebSecurity
static class DefaultAndJwtAuthenticationManagerConfig extends WebSecurityConfigurerAdapter {
AuthenticationManager defaultAuthenticationManager = mock(AuthenticationManager.class);
AuthenticationManager jwtAuthenticationManager = mock(AuthenticationManager.class);
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authenticationManager(this.defaultAuthenticationManager)
.authorizeRequests((authz) -> authz
.anyRequest().authenticated()
)
.oauth2ResourceServer((oauth2) -> oauth2
.jwt((jwt) -> jwt
.authenticationManager(this.jwtAuthenticationManager)
)
);
// @formatter:on
}
AuthenticationManager defaultAuthenticationManager() {
return this.defaultAuthenticationManager;
}
AuthenticationManager jwtAuthenticationManager() {
return this.jwtAuthenticationManager;
}
}
@EnableWebSecurity
static class CustomJwtValidatorConfig extends WebSecurityConfigurerAdapter {
@@ -2230,6 +2299,39 @@ public class OAuth2ResourceServerConfigurerTests {
}
@EnableWebSecurity
static class DefaultAndOpaqueTokenAuthenticationManagerConfig extends WebSecurityConfigurerAdapter {
AuthenticationManager defaultAuthenticationManager = mock(AuthenticationManager.class);
AuthenticationManager opaqueTokenAuthenticationManager = mock(AuthenticationManager.class);
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authenticationManager(this.defaultAuthenticationManager)
.authorizeRequests((authz) -> authz
.anyRequest().authenticated()
)
.oauth2ResourceServer((oauth2) -> oauth2
.opaqueToken((opaque) -> opaque
.authenticationManager(this.opaqueTokenAuthenticationManager)
)
);
// @formatter:on
}
AuthenticationManager defaultAuthenticationManager() {
return this.defaultAuthenticationManager;
}
AuthenticationManager opaqueTokenAuthenticationManager() {
return this.opaqueTokenAuthenticationManager;
}
}
@EnableWebSecurity
static class OpaqueAndJwtConfig extends WebSecurityConfigurerAdapter {

View File

@@ -163,6 +163,12 @@ public class Saml2LoginConfigurerTests {
performSaml2Login("ROLE_AUTH_MANAGER");
}
@Test
public void saml2LoginWhenDefaultAndSamlAuthenticationManagerThenSamlManagerIsUsed() throws Exception {
this.spring.register(Saml2LoginConfigWithDefaultAndCustomAuthenticationManager.class).autowire();
performSaml2Login("ROLE_AUTH_MANAGER");
}
@Test
public void saml2LoginWhenConfiguringAuthenticationDefaultsUsingCustomizerThenTheProviderIsConfigured()
throws Exception {
@@ -290,6 +296,24 @@ public class Saml2LoginConfigurerTests {
}
@EnableWebSecurity
@Import(Saml2LoginConfigBeans.class)
static class Saml2LoginConfigWithDefaultAndCustomAuthenticationManager extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
.authenticationManager(getAuthenticationManagerMock("DEFAULT_AUTH_MANAGER"))
.saml2Login((saml) -> saml
.authenticationManager(getAuthenticationManagerMock("ROLE_AUTH_MANAGER"))
);
super.configure(http);
// @formatter:on
}
}
@EnableWebSecurity
@Import(Saml2LoginConfigBeans.class)
static class Saml2LoginConfigWithAuthenticationDefaultsWithPostProcessor extends WebSecurityConfigurerAdapter {