1
0
mirror of synced 2026-05-22 21:33:16 +00:00

Move FACTOR_X509 into PreAuthenticatedAuthenticationProvider

Issue gh-17933
This commit is contained in:
Josh Cummings
2025-09-19 09:58:04 -06:00
parent e8accd0499
commit 0f4e1f2a2a
2 changed files with 22 additions and 33 deletions
@@ -17,18 +17,15 @@
package org.springframework.security.config.annotation.web.configurers;
import jakarta.servlet.http.HttpServletRequest;
import org.jspecify.annotations.Nullable;
import org.springframework.context.ApplicationContext;
import org.springframework.security.authentication.AuthenticationDetailsSource;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.HttpSecurityBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
import org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper;
import org.springframework.security.core.userdetails.UserDetailsService;
@@ -182,7 +179,8 @@ public final class X509Configurer<H extends HttpSecurityBuilder<H>>
public void init(H http) {
PreAuthenticatedAuthenticationProvider authenticationProvider = new PreAuthenticatedAuthenticationProvider();
authenticationProvider.setPreAuthenticatedUserDetailsService(getAuthenticationUserDetailsService(http));
http.authenticationProvider(new AuthorityGrantingAuthenticationProvider(authenticationProvider))
authenticationProvider.setGrantedAuthoritySupplier(() -> AuthorityUtils.createAuthorityList("FACTOR_X509"));
http.authenticationProvider(authenticationProvider)
.setSharedObject(AuthenticationEntryPoint.class, new Http403ForbiddenEntryPoint());
ExceptionHandlingConfigurer<H> exceptions = http.getConfigurer(ExceptionHandlingConfigurer.class);
if (exceptions != null) {
@@ -234,31 +232,4 @@ public final class X509Configurer<H extends HttpSecurityBuilder<H>>
return context.getBeanProvider(type).getIfUnique();
}
private static final class AuthorityGrantingAuthenticationProvider implements AuthenticationProvider {
private final AuthenticationProvider delegate;
private AuthorityGrantingAuthenticationProvider(AuthenticationProvider delegate) {
this.delegate = delegate;
}
@Override
public @Nullable Authentication authenticate(Authentication authentication) throws AuthenticationException {
Authentication result = this.delegate.authenticate(authentication);
if (result == null) {
return result;
}
return result
.toBuilder()
.authorities((a) -> a.add(new SimpleGrantedAuthority("FACTOR_X509")))
.build();
}
@Override
public boolean supports(Class<?> authentication) {
return true;
}
}
}
@@ -16,6 +16,11 @@
package org.springframework.security.web.authentication.preauth;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.function.Supplier;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jspecify.annotations.Nullable;
@@ -28,6 +33,7 @@ import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsChecker;
@@ -57,6 +63,8 @@ public class PreAuthenticatedAuthenticationProvider implements AuthenticationPro
private UserDetailsChecker userDetailsChecker = new AccountStatusUserDetailsChecker();
private Supplier<Collection<GrantedAuthority>> grantedAuthoritySupplier = List::of;
private boolean throwExceptionWhenTokenRejected;
private int order = -1; // default: same as non-ordered
@@ -98,8 +106,10 @@ public class PreAuthenticatedAuthenticationProvider implements AuthenticationPro
UserDetails userDetails = this.preAuthenticatedUserDetailsService
.loadUserDetails((PreAuthenticatedAuthenticationToken) authentication);
this.userDetailsChecker.check(userDetails);
Collection<GrantedAuthority> authorities = new LinkedHashSet<>(userDetails.getAuthorities());
authorities.addAll(this.grantedAuthoritySupplier.get());
PreAuthenticatedAuthenticationToken result = new PreAuthenticatedAuthenticationToken(userDetails,
authentication.getCredentials(), userDetails.getAuthorities());
authentication.getCredentials(), authorities);
result.setDetails(authentication.getDetails());
return result;
}
@@ -142,6 +152,14 @@ public class PreAuthenticatedAuthenticationProvider implements AuthenticationPro
this.userDetailsChecker = userDetailsChecker;
}
/**
* Sets authorities that this provider should grant once authentication completes
* @param grantedAuthoritySupplier the supplier that grants authorities
*/
public void setGrantedAuthoritySupplier(Supplier<Collection<GrantedAuthority>> grantedAuthoritySupplier) {
this.grantedAuthoritySupplier = grantedAuthoritySupplier;
}
@Override
public int getOrder() {
return this.order;