Spring security 弹簧安全x509 x509拖拉机
我正试图让一个Spring安全配置工作,但我有一些问题,我不知道该怎么办。我已成功地将x509与以下配置一起使用Spring security 弹簧安全x509 x509拖拉机,spring-security,x509,Spring Security,X509,我正试图让一个Spring安全配置工作,但我有一些问题,我不知道该怎么办。我已成功地将x509与以下配置一起使用 <security:http auto-config="true" use-expressions="true"> <security:x509 subject-principal-regex="CN=(.*?)," user-service-ref="rrportalUserDetailsService" /> <security:in
<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>
问题是证书的CN不足以让我正确授权和分配角色。我需要解析X509证书扩展中的一些项。我认为X509拖拉机非常适合我的需要,但我不知道如何正确连接
我有这个,但就AuthenticationEntrypoint而言,我不确定我需要什么。我是否可以实现自己的提取并将自定义字符串传递给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>
如果有人能给我指出正确的方向或给我指出一个配置示例,我将非常感激
谢谢大家 您可以在身份验证提供程序中使用自定义身份验证提供程序。在实现身份验证方法时,您可以从身份验证对象中提取任何附加信息,该对象应该是PreAuthenticateAuthenticationToken的实例,并根据需要对其进行处理。因此,您不需要自定义主体提取器。默认情况下,DaoAuthenticationProvider仅支持UsernamePasswordAuthenticationToken。另一种方法是将其子类化,并实现对两个身份验证令牌的支持
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));
}
}
公共类X509AuthenticationProvider实现AuthenticationProvider{
私有静态最终字符串CN_PATTERN=“CN=(.*)(:,|$)”;
私有静态最终字符串OU_PATTERN=“OU=(.*)(:,|$)”;
私有模式cnPattern=Pattern.compile(CN\u模式,Pattern.CASE\u不区分大小写);
私有模式ouPattern=Pattern.compile(OU\u模式,Pattern.CASE\u不区分大小写);
私有最终用户详细信息服务用户详细信息服务;
公共X509AuthenticationProvider(UserDetailsService UserDetailsService){
notNull(userDetailsService,“应提供userDetailsService”);
this.userDetailsService=userDetailsService;
}
@凌驾
公共身份验证(身份验证)引发AuthenticationException{
最终字符串凭据=authentication.getCredentials().toString();
Matcher Matcher=cnPattern.Matcher(凭证);
如果(!matcher.find()){
抛出新的BadCredentialsException(String.format(“在主题DN中找不到CN:{0}”,凭据));
}
字符串username=matcher.group(1);
matcher=ouPattern.matcher(凭证);
如果(!matcher.find()){
抛出新的BadCredentialsException(String.format(“在主题DN中找不到OU:{0}”,凭据));
}
username=matcher.group(1)+“\\”+用户名;
最终UserDetails UserDetails=userDetailsService.loadUserByUsername(用户名);
返回新的预验证身份验证令牌(userDetails,authentication.getCredentials(),userDetails.getAuthorities());
}
@凌驾
公共布尔支持(类身份验证){
返回(预验证DauthenticationToken.class.isAssignableFrom(验证));
}
}
那么,X509拖拉机是否不是在该实例中创建的正确对象?似乎构建提取器是“更正确”的方法?那不是真的吗?