Results 1 to 4 of 4

Thread: x509 Client Certificate

  1. #1
    Join Date
    Mar 2009
    Location
    New Jersey
    Posts
    44

    Default 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. #2
    Join Date
    Oct 2008
    Location
    Poland, Wrocław
    Posts
    424

    Default

    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

  3. #3
    Join Date
    Mar 2009
    Location
    New Jersey
    Posts
    44

    Default

    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>

  4. #4
    Join Date
    Oct 2008
    Location
    Poland, Wrocław
    Posts
    424

    Default

    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

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •