title: X509Authentication with Java and Spring Security
body: <p>In my application I'm trying to implement authentication using X509 certificates</p>
  <p>I found default solutions provided by the Spring Security framework as follows:</p>
  <ul>
  <li><a href="https://github.com/spring-projects/spring-security/blob/main/web/src/main/java/org/springframework/security/web/authentication/preauth/x509/X509AuthenticationFilter.java" rel="nofollow noreferrer">X509AuthenticationFilter</a></li>
  <li><a href="https://github.com/spring-projects/spring-security/blob/ad907457eeeee46da101215f5408d3cd98de4881/web/src/main/java/org/springframework/security/web/authentication/preauth/x509/X509PrincipalExtractor.java" rel="nofollow noreferrer">X509PrincipalExtractor</a></li>
  <li><a href="https://github.com/spring-projects/spring-ws/blob/main/spring-ws-security/src/main/java/org/springframework/ws/soap/security/x509/X509AuthenticationProvider.java" rel="nofollow noreferrer">X509AuthenticationProvider</a></li>
  <li><a href="https://github.com/spring-projects/spring-ws/blob/main/spring-ws-security/src/main/java/org/springframework/ws/soap/security/x509/X509AuthoritiesPopulator.java" rel="nofollow noreferrer">X509AuthoritiesPopulator</a></li>
  </ul>
  <p>Given how much I know about Spring Security, the purpose of these classes and interfaces is as follows:</p>
  <p><code>X509AuthenticationFilter</code> is responsible for intercepting the HTTP request, creating an authRequest token (of type <code>X509AuthenticationToken</code>) in <code>doFilter()</code> method and initializing the authentication process by delegating the token to the authManager. The authManager later delegates the authentication job to the <code>X509AuthenticationProvider</code></p>
  <p>The main goal of the <code>X509AuthenticationProvider</code> is to perform the authentication by extracting the UserDetails using <code>X509AuthoritiesPopulator</code> and setting it to the new <code>X509AuthenticationToken</code> that is later set in <code>SecurityContext</code>. After the new token has been set, the process is finished.</p>
  <p><code>X509PrincipalExtractor</code> is an interface, implementation of which should return a DN (Distinguished Name) from a certificate. However, it's not clear to me where it should be used. In my application I use it to get the DN and based on the DN I return a UserDetails instance inside <code>X509AuthoritiesPopulator</code>.</p>
  <p>My questions are the following:</p>
  <ol>
  <li>Where should I use the <code>X509PrincipalExtractor</code>? I put this interface inside my <code>X509AuthoritiesPopulator</code> to get the UserDetails instance based the returned string value of DN. Is that correct?</li>
  <li>Why is the <code>X509PrincipalExtractor</code> used in the default <code>X509AuthenticationFilter</code> provided by spring security in the method <code>getPreAuthenticatedPrincipal()</code>?</li>
  <li>What's the point of the method <code>getPreAuthenticatedPrincipal()</code> anyway? What it should look like in my class? I found it in the <code>doAuthenticate()</code> method in the <code>AbstractPreAuthenticatedProcessingFilter</code>, but from what I can gather, just an <code>X509Certificate</code> instance is enough to create an <code>X509AuthenticationToken</code>, there's no need for principle. Am I missing something?</li>
  </ol>
  <p>My doAuthenticate() method is below:</p>
  <pre><code>private void doAuthenticate(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
  {
      // why would I need principle? I found this in the doAuthenticate() of AbstractPreAuthenticatedProcessingFilter 
      Object principal = getPreAuthenticatedPrincipal(request);
      X509Certificate credentials = getPreAuthenticatedCredentials(request);
      try
      {
          X509AuthenticationToken authRequest = new X509AuthenticationToken(credentials);
          authRequest.setDetails(super.getAuthenticationDetailsSource().buildDetails(request));
          Authentication authResult = authenticationManager.authenticate(authRequest);
          super.successfulAuthentication(request, response, authResult);
      }
      catch (AuthenticationException e)
      {
          super.unsuccessfulAuthentication(request, response, e);
      }
  }
  </code></pre>
  <ol start="4">
  <li>In <code>AbstractPreAuthenticatedProcessingFilter</code> there's a method called <code>principalChanged()</code>. How come a principle can change? The certificate is always static and simply can't be modified.</li>
  </ol>