Spring security context 'principal' returns a String and not actual user data
<p>I'm working on an existing project at the buggy authentication part for an API. As a Spring beginner I feel like I'm missing something important about Security here so I would like some help or advice.
My version of Spring Security is <strong>3.2.5.RELEASE</strong>.</p>

<p>I have this method in one of my controllers:</p>

<pre><code>@Override
@ResponseBody
@ResponseStatus(HttpStatus.OK)
@RequestMapping(method = RequestMethod.POST, produces = "text/plain", consumes = "application/xml")
@PreAuthorize("principal.manager.id == #managerId and hasAuthority('ADMIN')")
public String create(@PathVariable("manager-id") Short managerId, @RequestBody Key key) {
    return super.create(managerId, key);
}
</code></pre>

<p>The important part here is the @Preauthorize line. Indeed, when I try and call this method <strong>as a non-authenticated user</strong> I get a failure, and logs tell me the following:</p>

<pre><code>Field or property 'manager' cannot be found on object of type 'java.lang.String'
</code></pre>

<p><em>Manager is a field from a custom User class, which implements Serializable and UserDetails.</em></p>

<p>I'm confused: why would the <strong>principal</strong> variable be a <strong>String</strong> and not something like a <strong>User</strong> object (for example) which is the kind of thing I'm expecting to use and get the info from. This error ends with:</p>

<pre><code>Wrapped by: java.lang.IllegalArgumentException:
Failed to evaluate expression "principal.manager.id == #managerId and hasAuthority('ADMIN')"
</code></pre>

<p>Because it obviously can't get a <em>manager</em> attribute from principal, which is a String variable.</p>

<p>To log more about this, I tried to externalize things a bit, and changed my Preauthorize line to:</p>

<pre><code>@PreAuthorize("hasAuthority('ADMIN') and @userService.hasRightManager(principal, #managerId)")
</code></pre>

<p>I implemented a very simple hasRightManager method: for now it does nothing except logging the value of the principal variable.
It returned "admin" in the logs, which is indeed a String and not a User object.</p>

<p>Now I'm stuck because even the Spring Security documentation seems to say that a UserDetails object (or some other user info class) should be expected when fetching this principal variable and all I get is a String:</p>

<blockquote>
  <p>Object getPrincipal() The identity of the principal being
  authenticated. In the case of an authentication request with username
  and password, this would be the username. Callers are expected to
  populate the principal for an authentication request. The
  AuthenticationManager implementation will often return an
  Authentication containing richer information as the principal for use
  by the application. Many of the authentication providers will create a
  UserDetails object as the principal.</p>
  
  <p>Returns: the Principal being authenticated or the authenticated
  principal after authentication.</p>
</blockquote>

<p>I was not the one implementing authentication for this API so it feels kind of blurry to me.</p>

<p>Knowing this, could you please shed some light on this type issue and give me a lead on how to do things differently and get a User object instead of a String when fetching principal?</p>

<p>Do not hesitate to ask me more questions if my explanation happens to be too incomplete to help my case. Thank you.</p>