2013-05-22 3 views
4

스프링 보안 구성을 작동 시키려고하는데 몇 가지 문제가있어 무엇을해야할지 모르겠습니다. 나는 성공적으로 다음과 같은 구성스프링 보안 x509 X509PrincipalExtractor

<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을 사용하고 있습니다. X509Certificate의 확장 기능 중 일부 항목을 구문 분석해야합니다. 나는 X509PrincipalExtractor가 내가 필요로하는 것에 완벽하다고 생각하지만, 올바르게 연결하는 방법을 알 수 없다.

나는 이것을 가지고 있지만 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> 

누군가가 올바른 방향으로 나를 가리키게하거나 샘플 구성을 가르쳐 주면 매우 감사 할 것입니다.

감사합니다. 모두들!

답변

3

인증 공급자에서 사용자 지정 AuthenticationProvider를 사용할 수 있습니다. authenticate 메소드를 구현하는 동안 PreAuthenticatedAuthenticationToken의 인스턴스 여야하는 Authentication 객체에서 추가 정보를 추출하여 필요한대로 처리 할 수 ​​있습니다. 따라서 사용자 지정 기본 추출기가 필요하지 않습니다. 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)); 
    } 
} 
+0

X509PrincipalExtractor는이 인스턴스에서 만들 수있는 적절한 개체가 아닙니다. 추출기를 만드는 것이 이렇게하는 "더 정확한"방법 인 것 같습니다. 그건 사실이 아닌가? – Mike