title: Injecting Custom Principal to Controllers by Spring Security
body: <p>servletApi() support of Spring Security is great. </p>
  
  <p>I want to inject custom Principal as this:</p>
  
  <pre><code>public interface UserPrincipal extends Principal {
     public Integer getId();
  }
  
  @RequestMapping(value = "/")
  public ResponseEntity&lt;List&lt;Conversation&gt;&gt; listAfter(UserPrincipal user){
     // implementation
  }  
  
  or
  
  
  @RequestMapping(value = "/")
  public ResponseEntity&lt;List&lt;Conversation&gt;&gt; listAfter(UserPrincipalImpl user){
     // implementation
  }
  </code></pre>
  
  <p>Spring has support for injecting <code>Principal</code> instances with the help of <code>ServletRequestMethodArgumentResolver</code>. </p>
  
  <p>It is injecting principal as this:</p>
  
  <pre><code>else if (Principal.class.isAssignableFrom(paramType)) {
      return request.getUserPrincipal();
  }
  </code></pre>
  
  <p>Here is the place where the problem begins. <code>request</code> is here an instance of <code>SecurityContextHolderAwareRequestWrapper</code>. It has an implementation of:</p>
  
  <pre><code>@Override
  public Principal getUserPrincipal() {
      Authentication auth = getAuthentication();
  
      if ((auth == null) || (auth.getPrincipal() == null)) {
          return null;
      }
  
      return auth;
   }
  </code></pre>
  
  <p>Because an <code>Authentication</code> is also an <code>Principal</code>. (The only part of spring security I did not like so far. I will ask this a separate question as well.)</p>
  
  <p>This is causing a problem. Because <code>Authentication</code> is a <code>Principal</code> not a <code>UserPrincipal</code>.</p>
  
  <p>How can I resolve this problem? Do I need to implement an authentication which is a UserPrincipal as well? Or should I change HandlerMethodArgumentResolver order a create a custom resolver? (This is not easy for Spring MVC because internal handlers has higher priority.)</p>
  
  <p>As a extra information: </p>
  
  <p>I am using Spring Security M2 and my configuration for <code>AuthenticationManagerBuilder</code> is simply:</p>
  
  <pre><code>@Override
  protected void registerAuthentication(AuthenticationManagerBuilder auth) throws Exception        {
  
    auth
       .userDetailsService(detailsService);
  }
  </code></pre>
  
  <p>Any help?</p>