|
@@ -17,14 +17,18 @@
|
|
|
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.userdetails.AuthenticationUserDetailsService;
|
|
|
import org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper;
|
|
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
|
@@ -37,6 +41,7 @@ import org.springframework.security.web.authentication.preauth.x509.SubjectDnX50
|
|
|
import org.springframework.security.web.authentication.preauth.x509.X509AuthenticationFilter;
|
|
|
import org.springframework.security.web.authentication.preauth.x509.X509PrincipalExtractor;
|
|
|
import org.springframework.security.web.context.RequestAttributeSecurityContextRepository;
|
|
|
+import org.springframework.security.web.util.matcher.AnyRequestMatcher;
|
|
|
|
|
|
/**
|
|
|
* Adds X509 based pre authentication to an application. Since validating the certificate
|
|
@@ -177,8 +182,12 @@ public final class X509Configurer<H extends HttpSecurityBuilder<H>>
|
|
|
public void init(H http) {
|
|
|
PreAuthenticatedAuthenticationProvider authenticationProvider = new PreAuthenticatedAuthenticationProvider();
|
|
|
authenticationProvider.setPreAuthenticatedUserDetailsService(getAuthenticationUserDetailsService(http));
|
|
|
- http.authenticationProvider(authenticationProvider)
|
|
|
+ http.authenticationProvider(new AuthorityGrantingAuthenticationProvider(authenticationProvider))
|
|
|
.setSharedObject(AuthenticationEntryPoint.class, new Http403ForbiddenEntryPoint());
|
|
|
+ ExceptionHandlingConfigurer<H> exceptions = http.getConfigurer(ExceptionHandlingConfigurer.class);
|
|
|
+ if (exceptions != null) {
|
|
|
+ exceptions.defaultAuthenticationEntryPointFor(new Http403ForbiddenEntryPoint(), AnyRequestMatcher.INSTANCE);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -225,4 +234,31 @@ 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;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
}
|