title: Spring Security Cookie + JWT authentication
body: <p>I must say I am very confused about the entire model and I need help gluing all the floating pieces together.</p>
  
  <p>I am not doing Spring REST, just plain WebMVC controllers.</p>
  
  <p>My mission:
  I want a form login with a username + pass authentication. I want to authenticate against a 3rd party service. Upon success I want to return a cookie but NOT use the default cookie token mechanism. I want the cookie to have a JWT token instead. By leveraging the cookie mechanism every request will be sent with the JWT.</p>
  
  <p>So to break it down I have the following modules to take care of:</p>
  
  <ol>
  <li>do authentication against a 3rd party service when doing a user + pas logi
  n</li>
  <li><p>replace cookie session token with my custom implementation upon successful auth</p></li>
  <li><p>upon every request parse the JWT from the cookie ( using a filter )</p></li>
  <li><p>extract user details / data from the JWT to be accessible to the controllers</p></li>
  </ol>
  
  <p>What's confusing? ( please correct me where I am wrong )</p>
  
  <p><strong>3rd party authentication</strong></p>
  
  <p>to authenticate against a 3rd party I will need to have a custom provider by extending AuthenticationProvider</p>
  
  <pre><code>public class JWTTokenAuthenticationProvider implements AuthenticationProvider { 
  
        @Override
        public Authentication authenticate( Authentication authentication ) throws AuthenticationException {
  
            // auth against 3rd party
  
            // return Authentication
            return new UsernamePasswordAuthenticationToken( name, password, new ArrayList&lt;&gt;() );
  
        }
  
        @Override
        public boolean supports(Class&lt;?&gt; authentication) {
            return authentication.equals( UsernamePasswordAuthenticationToken.class );
        }
  
  }
  </code></pre>
  
  <p>Questions:</p>
  
  <ul>
  <li>is this provider executed upon successful authentication / login when user submits a form user + pass? if so that how is that related to AbstractAuthenticationProcessingFilter#successfulAuthentication?</li>
  <li>do I have to return an instance of UsernamePasswordAuthenticationToken?</li>
  <li>do I have to support UsernamePasswordAuthenticationToken to get user + pass here?</li>
  </ul>
  
  <p><strong>replace cookie token with a JWT</strong></p>
  
  <p>No idea how to do this gracefully, I can think of a number of ways but they not Spring Security ways and I don't want to break out of the flow. Would be thankful for any suggestions here!</p>
  
  <p><strong>parse the JWT with every request from a cookie</strong></p>
  
  <p>From what I understand I need to extend AbstractAuthenticationProcessingFilter like so</p>
  
  <pre><code>public class CookieAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
  
      @Override
      public Authentication attemptAuthentication( HttpServletRequest request, HttpServletResponse response )
              throws AuthenticationException, IOException, ServletException {
  
          String token = "";
  
          // get token from a Cookie
  
          // create an instance to Authentication
          TokenAuthentication authentication = new TokenAuthentication(null, null);
  
          return getAuthenticationManager().authenticate(tokenAuthentication);
  
      }
  
      @Override
      public void doFilter(ServletRequest req, ServletResponse res,
                       FilterChain chain) throws IOException, ServletException {
          super.doFilter(req, res, chain);
      }
  
  }
  </code></pre>
  
  <p>Questions:</p>
  
  <ul>
  <li>when is AbstractAuthenticationProcessingFilter#successfulAuthentication called? is it called with the user logs in or when the JWT token been validated successfully?</li>
  <li>is there any relation between this filter and the custom provider I posted previously? The manager will supposedly call the custom provider based on the token instance which is matched with what the provider supports via the support method?</li>
  </ul>
  
  <p>It seems as if I have all the pieces I need, except the cookie session replacement, but I cannot put them into a single coherent model and I need from somebody who understand the mechanics well enough so I can glue all of this into a single module.</p>
  
  <p><strong>UPDATE 1</strong></p>
  
  <p>OK, I think I am getting where this is starting... <a href="https://github.com/spring-projects/spring-security/blob/master/web/src/main/java/org/springframework/security/web/authentication/UsernamePasswordAuthenticationFilter.java" rel="noreferrer">https://github.com/spring-projects/spring-security/blob/master/web/src/main/java/org/springframework/security/web/authentication/UsernamePasswordAuthenticationFilter.java</a></p>
  
  <p>This Filter registers itself to POST -> "/login" and than creates an instance of UsernamePasswordAuthenticationToken and passes the control to the next filter.</p>
  
  <p>Question is where the cookie session is set....</p>
  
  <p><strong>UPDATE 2</strong></p>
  
  <p>This section of the dos gives the top level flow that I was missing, for whoever is going through this take a look here... <a href="http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#tech-intro-authentication" rel="noreferrer">http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#tech-intro-authentication</a></p>
  
  <p>This section regarding the AuthenticationProvider... <a href="http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#core-services-authentication-manager" rel="noreferrer">http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#core-services-authentication-manager</a></p>
  
  <p><strong>UPDATE 3 - working case, is this the best way??</strong></p>
  
  <p>So after digging through the Spring Security docs and their sources I got the initial model to work. Now, doing this, I realized there is more than one way to do it. Any advice of why picking this way VS what Denys proposed below?</p>
  
  <p>Working example below...</p>