mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-05-31 17:22:13 +00:00
Set details on authentication token created by HttpServlet3RequestFactory
Currently the login mechanism when triggered by executing HttpServlet3RequestFactory#login does not set any details on the underlying authentication token that is authenticated. This change adds an AuthenticationDetailsSource on the HttpServlet3RequestFactory, which defaults to a WebAuthenticationDetailsSource. Closes gh-9579
This commit is contained in:
parent
074e38d565
commit
925d531cbe
@ -21,6 +21,7 @@ import java.util.List;
|
|||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.security.authentication.AuthenticationDetailsSource;
|
||||||
import org.springframework.security.authentication.AuthenticationManager;
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
import org.springframework.security.authentication.AuthenticationTrustResolver;
|
import org.springframework.security.authentication.AuthenticationTrustResolver;
|
||||||
import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
|
import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
|
||||||
@ -90,6 +91,11 @@ public final class ServletApiConfigurer<H extends HttpSecurityBuilder<H>>
|
|||||||
if (trustResolver != null) {
|
if (trustResolver != null) {
|
||||||
this.securityContextRequestFilter.setTrustResolver(trustResolver);
|
this.securityContextRequestFilter.setTrustResolver(trustResolver);
|
||||||
}
|
}
|
||||||
|
AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = http
|
||||||
|
.getSharedObject(AuthenticationDetailsSource.class);
|
||||||
|
if (authenticationDetailsSource != null) {
|
||||||
|
this.securityContextRequestFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
|
||||||
|
}
|
||||||
ApplicationContext context = http.getSharedObject(ApplicationContext.class);
|
ApplicationContext context = http.getSharedObject(ApplicationContext.class);
|
||||||
if (context != null) {
|
if (context != null) {
|
||||||
String[] grantedAuthorityDefaultsBeanNames = context.getBeanNamesForType(GrantedAuthorityDefaults.class);
|
String[] grantedAuthorityDefaultsBeanNames = context.getBeanNamesForType(GrantedAuthorityDefaults.class);
|
||||||
|
@ -30,6 +30,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.security.access.AccessDeniedException;
|
import org.springframework.security.access.AccessDeniedException;
|
||||||
|
import org.springframework.security.authentication.AuthenticationDetailsSource;
|
||||||
import org.springframework.security.authentication.AuthenticationManager;
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
import org.springframework.security.authentication.AuthenticationTrustResolver;
|
import org.springframework.security.authentication.AuthenticationTrustResolver;
|
||||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||||
@ -149,6 +150,15 @@ public class ServletApiConfigurerTests {
|
|||||||
verify(SharedTrustResolverConfig.TR, atLeastOnce()).isAnonymous(any());
|
verify(SharedTrustResolverConfig.TR, atLeastOnce()).isAnonymous(any());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void configureWhenSharedObjectAuthenticationDetailsSourceThenAuthenticationDetailsSourceUsed() {
|
||||||
|
this.spring.register(SharedAuthenticationDetailsSourceConfig.class).autowire();
|
||||||
|
SecurityContextHolderAwareRequestFilter scaFilter = getFilter(SecurityContextHolderAwareRequestFilter.class);
|
||||||
|
AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = getFieldValue(scaFilter,
|
||||||
|
"authenticationDetailsSource");
|
||||||
|
assertThat(authenticationDetailsSource).isEqualTo(SharedAuthenticationDetailsSourceConfig.ADS);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void requestWhenServletApiWithDefaultsInLambdaThenUsesDefaultRolePrefix() throws Exception {
|
public void requestWhenServletApiWithDefaultsInLambdaThenUsesDefaultRolePrefix() throws Exception {
|
||||||
this.spring.register(ServletApiWithDefaultsInLambdaConfig.class, AdminController.class).autowire();
|
this.spring.register(ServletApiWithDefaultsInLambdaConfig.class, AdminController.class).autowire();
|
||||||
@ -321,6 +331,22 @@ public class ServletApiConfigurerTests {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@EnableWebSecurity
|
||||||
|
static class SharedAuthenticationDetailsSourceConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
static AuthenticationDetailsSource<HttpServletRequest, ?> ADS = spy(AuthenticationDetailsSource.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure(HttpSecurity http) {
|
||||||
|
// @formatter:off
|
||||||
|
http
|
||||||
|
.setSharedObject(AuthenticationDetailsSource.class, ADS);
|
||||||
|
// @formatter:on
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
static class ServletApiWithDefaultsInLambdaConfig extends WebSecurityConfigurerAdapter {
|
static class ServletApiWithDefaultsInLambdaConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ import org.apache.commons.logging.Log;
|
|||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
|
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
|
||||||
|
import org.springframework.security.authentication.AuthenticationDetailsSource;
|
||||||
import org.springframework.security.authentication.AuthenticationManager;
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
import org.springframework.security.authentication.AuthenticationTrustResolver;
|
import org.springframework.security.authentication.AuthenticationTrustResolver;
|
||||||
import org.springframework.security.authentication.AuthenticationTrustResolverImpl;
|
import org.springframework.security.authentication.AuthenticationTrustResolverImpl;
|
||||||
@ -42,6 +43,7 @@ import org.springframework.security.core.AuthenticationException;
|
|||||||
import org.springframework.security.core.context.SecurityContext;
|
import org.springframework.security.core.context.SecurityContext;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||||
|
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
|
||||||
import org.springframework.security.web.authentication.logout.LogoutHandler;
|
import org.springframework.security.web.authentication.logout.LogoutHandler;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
@ -79,6 +81,8 @@ final class HttpServlet3RequestFactory implements HttpServletRequestFactory {
|
|||||||
|
|
||||||
private AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
|
private AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
|
||||||
|
|
||||||
|
private AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = new WebAuthenticationDetailsSource();
|
||||||
|
|
||||||
private AuthenticationEntryPoint authenticationEntryPoint;
|
private AuthenticationEntryPoint authenticationEntryPoint;
|
||||||
|
|
||||||
private AuthenticationManager authenticationManager;
|
private AuthenticationManager authenticationManager;
|
||||||
@ -158,6 +162,18 @@ final class HttpServlet3RequestFactory implements HttpServletRequestFactory {
|
|||||||
this.trustResolver = trustResolver;
|
this.trustResolver = trustResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the {@link AuthenticationDetailsSource} to be used. The default is
|
||||||
|
* {@link WebAuthenticationDetailsSource}.
|
||||||
|
* @param authenticationDetailsSource the {@link AuthenticationDetailsSource} to use.
|
||||||
|
* Cannot be null.
|
||||||
|
*/
|
||||||
|
void setAuthenticationDetailsSource(
|
||||||
|
AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource) {
|
||||||
|
Assert.notNull(authenticationDetailsSource, "authenticationDetailsSource cannot be null");
|
||||||
|
this.authenticationDetailsSource = authenticationDetailsSource;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HttpServletRequest create(HttpServletRequest request, HttpServletResponse response) {
|
public HttpServletRequest create(HttpServletRequest request, HttpServletResponse response) {
|
||||||
return new Servlet3SecurityContextHolderAwareRequestWrapper(request, this.rolePrefix, response);
|
return new Servlet3SecurityContextHolderAwareRequestWrapper(request, this.rolePrefix, response);
|
||||||
@ -233,7 +249,11 @@ final class HttpServlet3RequestFactory implements HttpServletRequestFactory {
|
|||||||
private Authentication getAuthentication(AuthenticationManager authManager, String username, String password)
|
private Authentication getAuthentication(AuthenticationManager authManager, String username, String password)
|
||||||
throws ServletException {
|
throws ServletException {
|
||||||
try {
|
try {
|
||||||
return authManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
|
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(username,
|
||||||
|
password);
|
||||||
|
Object details = HttpServlet3RequestFactory.this.authenticationDetailsSource.buildDetails(this);
|
||||||
|
authentication.setDetails(details);
|
||||||
|
return authManager.authenticate(authentication);
|
||||||
}
|
}
|
||||||
catch (AuthenticationException ex) {
|
catch (AuthenticationException ex) {
|
||||||
SecurityContextHolder.clearContext();
|
SecurityContextHolder.clearContext();
|
||||||
|
@ -27,12 +27,14 @@ import javax.servlet.ServletResponse;
|
|||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.springframework.security.authentication.AuthenticationDetailsSource;
|
||||||
import org.springframework.security.authentication.AuthenticationManager;
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
import org.springframework.security.authentication.AuthenticationTrustResolver;
|
import org.springframework.security.authentication.AuthenticationTrustResolver;
|
||||||
import org.springframework.security.authentication.AuthenticationTrustResolverImpl;
|
import org.springframework.security.authentication.AuthenticationTrustResolverImpl;
|
||||||
import org.springframework.security.core.context.SecurityContext;
|
import org.springframework.security.core.context.SecurityContext;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||||
|
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
|
||||||
import org.springframework.security.web.authentication.logout.LogoutHandler;
|
import org.springframework.security.web.authentication.logout.LogoutHandler;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.web.filter.GenericFilterBean;
|
import org.springframework.web.filter.GenericFilterBean;
|
||||||
@ -80,6 +82,8 @@ public class SecurityContextHolderAwareRequestFilter extends GenericFilterBean {
|
|||||||
|
|
||||||
private AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
|
private AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
|
||||||
|
|
||||||
|
private AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = new WebAuthenticationDetailsSource();
|
||||||
|
|
||||||
public void setRolePrefix(String rolePrefix) {
|
public void setRolePrefix(String rolePrefix) {
|
||||||
Assert.notNull(rolePrefix, "Role prefix must not be null");
|
Assert.notNull(rolePrefix, "Role prefix must not be null");
|
||||||
this.rolePrefix = rolePrefix;
|
this.rolePrefix = rolePrefix;
|
||||||
@ -172,9 +176,23 @@ public class SecurityContextHolderAwareRequestFilter extends GenericFilterBean {
|
|||||||
updateFactory();
|
updateFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the {@link AuthenticationDetailsSource} to be used. The default is
|
||||||
|
* {@link WebAuthenticationDetailsSource}.
|
||||||
|
* @param authenticationDetailsSource the {@link AuthenticationDetailsSource} to use.
|
||||||
|
* Cannot be null.
|
||||||
|
*/
|
||||||
|
public void setAuthenticationDetailsSource(
|
||||||
|
AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource) {
|
||||||
|
Assert.notNull(authenticationDetailsSource, "authenticationDetailsSource cannot be null");
|
||||||
|
this.authenticationDetailsSource = authenticationDetailsSource;
|
||||||
|
updateFactory();
|
||||||
|
}
|
||||||
|
|
||||||
private HttpServletRequestFactory createServlet3Factory(String rolePrefix) {
|
private HttpServletRequestFactory createServlet3Factory(String rolePrefix) {
|
||||||
HttpServlet3RequestFactory factory = new HttpServlet3RequestFactory(rolePrefix);
|
HttpServlet3RequestFactory factory = new HttpServlet3RequestFactory(rolePrefix);
|
||||||
factory.setTrustResolver(this.trustResolver);
|
factory.setTrustResolver(this.trustResolver);
|
||||||
|
factory.setAuthenticationDetailsSource(this.authenticationDetailsSource);
|
||||||
factory.setAuthenticationEntryPoint(this.authenticationEntryPoint);
|
factory.setAuthenticationEntryPoint(this.authenticationEntryPoint);
|
||||||
factory.setAuthenticationManager(this.authenticationManager);
|
factory.setAuthenticationManager(this.authenticationManager);
|
||||||
factory.setLogoutHandlers(this.logoutHandlers);
|
factory.setLogoutHandlers(this.logoutHandlers);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user