theotherian
theotherian

Reputation: 96

In Spring Security, why does SecurityExpressionRoot#isAuthenticated only check !isAnonymous?

When configuring web security and specifying something like .anyRequest().authenticated(), behind the scenes Spring will eventually invoke SecurityExpressionRoot.isAuthenticated() on the request. The instance of SecurityExpressionRoot has a field that is pointed to the current Authentication instance associated with the request.

The implementation of SecurityExpressionRoot.isAuthenticated() looks like this:

@Override
public final boolean isAuthenticated() {
  return !isAnonymous();
}

What I don't understand is why it's not invoking this.authentication.isAuthenticated() instead. SecurityExpressionRoot's isAnonymous() method is also public, and in my mind isAuthenticated() and isAnonymous() don't seem like logical opposites to one another (i.e. just because you're not authenticated, perhaps due to an expired session, doesn't seem like it automatically implies we don't know who the user is).

I'm guessing there are greater implications around what anonymous implies in the greater Spring Security taxonomy, but I don't know what they are and haven't found anything in the docs yet. Hoping someone could tell me why it's correct that this method doesn't simply invoke this.authentication.isAuthenticated() instead.

Upvotes: 0

Views: 424

Answers (1)

Marcus Hert da Coregio
Marcus Hert da Coregio

Reputation: 6308

I have some reasons that I remember now:

  1. Authentication can be null, therefore a NullPointerException may occur.
  2. Users can provide an AuthenticationTrustResolver of their own and customize what isAnonymous means.
  3. You could have a custom type of Authentication, let's say MultiFactorAuthentication, to identify that you have not finished MFA authentication yet, and this authentication might be anonymous. You have provided your credentials, isAuthenticated = true, but the authentication process is not finished. See this sample.

Those methods are public but they are final, you can't override them. Instead, you have to customize the AuthenticationTrustResolver.

Upvotes: 2

Related Questions