Spring-Security x509 X509PrincipalExtractor

I am trying to get Spring security configuration, but I have some problems and I'm not sure what to do. I successfully used x509 with the following configuration

<security:http auto-config="true" use-expressions="true"> <security:x509 subject-principal-regex="CN=(.*?)," user-service-ref="rrportalUserDetailsService" /> <security:intercept-url pattern="/selfRegistration/**" access="hasRole('ROLE_USER')" requires-channel="https"/> <security:intercept-url pattern="/**" access="permitAll" requires-channel="http"/> <security:port-mappings> <security:port-mapping http="8080" https="8443"/> </security:port-mappings> </security:http> 

The problem is that the CN certificate is not enough for me to authorize and assign my roles. I need to parse some elements from the X509Certificate extensions. I think the X509PrincipalExtractor is perfect for what I need, but I cannot figure out how to properly connect it.

I have this, but I'm not sure what I need as much as AuthenticationEntrypoint. Can I not just implement my own extraction and pass the user string to my UserDetailsService?

 <security:http auto-config="false" entry-point-ref="????" use-expressions="true"> <security:intercept-url pattern="/selfRegistration/**" access="hasRole('ROLE_USER')" requires-channel="https"/> <security:intercept-url pattern="/**" access="permitAll" requires-channel="http"/> <security:port-mappings> <security:port-mapping http="8080" https="8443"/> </security:port-mappings> <security:custom-filter position="X509_FILTER" ref="myX509AuthenticationFilter" /> </security:http> <security:authentication-manager alias="authenticationManager"> <security:authentication-provider user-service-ref="rrportalUserDetailsService"> </security:authentication-provider> </security:authentication-manager> <bean id="myX509AuthenticationFilter" class="org.springframework.security.web.authentication.preauth.x509.X509AuthenticationFilter"> <property name="authenticationManager" ref="authenticationManager" /> <property name="principalExtractor"> <bean class="com.ctc.rrportal.security.rrportalX509PrincipalExtractor" /> </property></bean> 

If someone can point me in the right direction or point me to a sample configuration, I would be very grateful.

Thanks everyone!

+4
source share
1 answer

You can use custom AuthenticationProvider in your authentication provider. When implementing the authentication method, you can extract any additional information from the authentication object, which must be an instance of PreAuthenticatedAuthenticationToken, and process it as necessary. Thus, you do not need a special main extractor. DaoAuthenticationProvider by default only supports UsernamePasswordAuthenticationToken. Another way is to subclass and implement authentication token support.

 public class X509AuthenticationProvider implements AuthenticationProvider { private static final String CN_PATTERN = "CN=(.*?)(?:,|$)"; private static final String OU_PATTERN = "OU=(.*?)(?:,|$)"; private Pattern cnPattern = Pattern.compile(CN_PATTERN, Pattern.CASE_INSENSITIVE); private Pattern ouPattern = Pattern.compile(OU_PATTERN, Pattern.CASE_INSENSITIVE); private final UserDetailsService userDetailsService; public X509AuthenticationProvider(UserDetailsService userDetailsService) { Assert.notNull(userDetailsService, "UserDetailsService should be provided"); this.userDetailsService = userDetailsService; } @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { final String credentials = authentication.getCredentials().toString(); Matcher matcher = cnPattern.matcher(credentials); if (!matcher.find()) { throw new BadCredentialsException(String.format("CN not found in subject DN: {0}", credentials)); } String username = matcher.group(1); matcher = ouPattern.matcher(credentials); if (!matcher.find()) { throw new BadCredentialsException(String.format("OU not found in subject DN: {0}", credentials)); } username = matcher.group(1) + "\\" + username; final UserDetails userDetails = userDetailsService.loadUserByUsername(username); return new PreAuthenticatedAuthenticationToken(userDetails, authentication.getCredentials(), userDetails.getAuthorities()); } @Override public boolean supports(Class<?> authentication) { return (PreAuthenticatedAuthenticationToken.class.isAssignableFrom(authentication)); } } 
+3
source

Source: https://habr.com/ru/post/1482199/


All Articles