mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-05-31 09:12:14 +00:00
Detect UserDetailsService bean in remember me
Closes gh-11170
This commit is contained in:
parent
a3e7e54b70
commit
8e34cedcfe
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2015 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.
|
||||||
@ -18,6 +18,8 @@ package org.springframework.security.config.annotation.web.configurers;
|
|||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.security.authentication.AuthenticationManager;
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
import org.springframework.security.authentication.RememberMeAuthenticationProvider;
|
import org.springframework.security.authentication.RememberMeAuthenticationProvider;
|
||||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||||
@ -403,7 +405,7 @@ public final class RememberMeConfigurer<H extends HttpSecurityBuilder<H>>
|
|||||||
*/
|
*/
|
||||||
private UserDetailsService getUserDetailsService(H http) {
|
private UserDetailsService getUserDetailsService(H http) {
|
||||||
if (this.userDetailsService == null) {
|
if (this.userDetailsService == null) {
|
||||||
this.userDetailsService = http.getSharedObject(UserDetailsService.class);
|
this.userDetailsService = getSharedOrBean(http, UserDetailsService.class);
|
||||||
}
|
}
|
||||||
Assert.state(this.userDetailsService != null,
|
Assert.state(this.userDetailsService != null,
|
||||||
() -> "userDetailsService cannot be null. Invoke " + RememberMeConfigurer.class.getSimpleName()
|
() -> "userDetailsService cannot be null. Invoke " + RememberMeConfigurer.class.getSimpleName()
|
||||||
@ -431,4 +433,25 @@ public final class RememberMeConfigurer<H extends HttpSecurityBuilder<H>>
|
|||||||
return this.key;
|
return this.key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private <C> C getSharedOrBean(H http, Class<C> type) {
|
||||||
|
C shared = http.getSharedObject(type);
|
||||||
|
if (shared != null) {
|
||||||
|
return shared;
|
||||||
|
}
|
||||||
|
return getBeanOrNull(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> T getBeanOrNull(Class<T> type) {
|
||||||
|
ApplicationContext context = getBuilder().getSharedObject(ApplicationContext.class);
|
||||||
|
if (context == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return context.getBean(type);
|
||||||
|
}
|
||||||
|
catch (NoSuchBeanDefinitionException ex) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2019 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.
|
||||||
@ -42,6 +42,7 @@ import org.springframework.security.core.userdetails.User;
|
|||||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
|
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
|
||||||
import org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers;
|
import org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers;
|
||||||
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
import org.springframework.security.web.authentication.RememberMeServices;
|
import org.springframework.security.web.authentication.RememberMeServices;
|
||||||
import org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter;
|
import org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter;
|
||||||
import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices;
|
import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices;
|
||||||
@ -117,6 +118,20 @@ public class RememberMeConfigurerTests {
|
|||||||
verify(DuplicateDoesNotOverrideConfig.userDetailsService).loadUserByUsername("user");
|
verify(DuplicateDoesNotOverrideConfig.userDetailsService).loadUserByUsername("user");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void rememberMeWhenUserDetailsServiceNotConfiguredThenUsesBean() throws Exception {
|
||||||
|
this.spring.register(UserDetailsServiceBeanConfig.class).autowire();
|
||||||
|
MvcResult mvcResult = this.mvc.perform(post("/login").with(csrf()).param("username", "user")
|
||||||
|
.param("password", "password").param("remember-me", "true")).andReturn();
|
||||||
|
Cookie rememberMeCookie = mvcResult.getResponse().getCookie("remember-me");
|
||||||
|
// @formatter:off
|
||||||
|
MockHttpServletRequestBuilder request = get("/abc").cookie(rememberMeCookie);
|
||||||
|
SecurityMockMvcResultMatchers.AuthenticatedMatcher remembermeAuthentication = authenticated()
|
||||||
|
.withAuthentication((auth) -> assertThat(auth).isInstanceOf(RememberMeAuthenticationToken.class));
|
||||||
|
// @formatter:on
|
||||||
|
this.mvc.perform(request).andExpect(remembermeAuthentication);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void loginWhenRememberMeTrueThenRespondsWithRememberMeCookie() throws Exception {
|
public void loginWhenRememberMeTrueThenRespondsWithRememberMeCookie() throws Exception {
|
||||||
this.spring.register(RememberMeConfig.class).autowire();
|
this.spring.register(RememberMeConfig.class).autowire();
|
||||||
@ -370,6 +385,26 @@ public class RememberMeConfigurerTests {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@EnableWebSecurity
|
||||||
|
static class UserDetailsServiceBeanConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
||||||
|
// @formatter:off
|
||||||
|
http
|
||||||
|
.formLogin(withDefaults())
|
||||||
|
.rememberMe(withDefaults());
|
||||||
|
// @formatter:on
|
||||||
|
return http.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
UserDetailsService customUserDetailsService() {
|
||||||
|
return new InMemoryUserDetailsManager(PasswordEncodedUser.user());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
static class RememberMeConfig extends WebSecurityConfigurerAdapter {
|
static class RememberMeConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user