Announcement Announcement Module
Collapse
No announcement yet.
x509 Client Certificate Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • x509 Client Certificate

    I am using x509 to read client certificate and pass the value to userdetailsservice. It works (using following config) however
    subject-principal-regex="CN=(.*?) only provides user name from subject which is not enough for our implementation. How do I access additional information(such as uid, issuer..)
    from client certificate using x509?


    Config:

    <http auto-config="true">
    <intercept-url pattern="/Home.htm" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <x509 subject-principal-regex="CN=(.*?)," user-service-ref="userDetailsService" />
    </http>


    If x509 cannot, how do I pass client certificate data into userDetailsService so that I can
    authenticate?

    Can someone help?

  • #2
    Hi

    First - implement your own org.springframework.security.web.authentication.pr eauth.x509.X509PrincipalExtractor:
    Code:
    public class MySpecialX509PrincipalExtractor implements X509PrincipalExtractor
    {
       private static Pattern serialNumber = Pattern.compile("serialNumber=([^=,]*)", Pattern.CASE_INSENSITIVE);
    
       public Object extractPrincipal(X509Certificate cert)
       {
          String name = cert.getSubjectDN().getName();
          Matcher m = serialNumber.matcher(name);
    
          if (!m.find())
             throw new BadCredentialsException("There's no serialNumber field in provided certificate.");
    
          return m.group(1);
       }
    }
    Then you have to use it in Spring-Security config:
    Code:
       <http auto-config="false" entry-point-ref="formLogin" servlet-api-provision="false">
          <!-- zasoby niechronione -->
          <intercept-url pattern="/**/*.css" filters="none" />
          ...
          <!-- custom X509 filter  -->
          <custom-filter position="X509_FILTER" ref="myX509AuthenticationFilter" />
       </http>
       ...
       <beans:bean id="myX509AuthenticationFilter" class="org.springframework.security.web.authentication.preauth.x509.X509AuthenticationFilter">
          <beans:description>By default, X509 filter creates its own authManager with its own provider. Here we'll use a shared one</beans:description>
          <beans:property name="authenticationManager" ref="authenticationManager" />
          <beans:property name="principalExtractor">
             <beans:bean class="MySpecialX509PrincipalExtractor" />
          </beans:property>
       </beans:bean>
    It works for me

    regards
    Grzegorz Grzybek

    Comment


    • #3
      Hi Grzegorz,
      With the code you provided, I was able to get the serialnumber+user. Now I need to pass it to userdetailsservice so that I can authenticate the user. How does it work?
      Thanks very much for your help. I am moving forward now.

      Here's my config:

      </http>

      <beans:bean id="myX509AuthenticationFilter" class="org.springframework.security.web.authentica tion.preauth.x509.X509AuthenticationFilter">
      <beans:description>By default, X509 filter creates its own authManager with its own provider. Here we'll use a shared one</beans:description>
      <beansroperty name="authenticationManager" ref="authenticationManager" />
      <beansroperty name="principalExtractor">
      <beans:bean class="com.coba.rwa.util.MySpecialX509PrincipalExt ractor" />
      </beansroperty>
      </beans:bean>


      <authentication-manager alias="authenticationManager">
      <authentication-provider user-service-ref='userDetailsService'/>
      </authentication-manager>



      <beans:bean id="userDetailsService" class="com.coba.rwa.db.GDSService">
      </beans:bean>

      Comment


      • #4
        Hi

        Your configuration states that the AuthenticationManager will use org.springframework.security.authentication.dao.Da oAuthenticationProvider with your provided userDetailsService.

        So with X509_FILTER, which should be org.springframework.security.web.authentication.pr eauth.x509.X509AuthenticationFilter (with your own principalExtractor) the flow is:
        - X509AuthenticationFilter in its (parent class') doAuthenticate method retrieves your principal (with your extractor) and credentials (entire X.509 certificate)
        - these objects are packed into PreAuthenticatedAuthenticationToken
        - this token is provided to authenticationManager.authenticate() method
        - authenticationManager uses all providers (in your case only one - DaoAuthenticationProvider) to
        --- check whether it supports the token
        --- authenticate the token

        Unfortunately DaoAuthenticationProvider supports only UsernamePasswordAuthenticationToken tokens, so you have to implement (derive) your own if you e.g. want to authenticate user in database. But maybe you want to use LDAP? I don't know what your userDetailsService does, but I hope you get an idea of Spring-Security's flow.

        regards
        Grzegorz Grzybek

        Comment

        Working...
        X