Spring Security
  1. Spring Security
  2. SEC-1101

SecurityContextHolderAwareRequestWrapper isUserInRole always returns null when user is anonymously authenticated

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Won't Fix
    • Affects Version/s: 2.0.4
    • Fix Version/s: 3.0.0 M1
    • Component/s: Core
    • Labels:
      None

      Description

      In our application a user can be fully authenticated or anymous authenticated.
      In the later case the security token is the AnonymousAuthenticationToken.

      When a user is anonymously authenticated and I the isUserInRole('ROLE_ANONYMOUS') functionality on the In HttpServletRequest always get 'false'.
      I verified the SecurityContextHolder.getContext().getAuthentication() -> I can clearly see that the token is AnonymousAuthenticationToken and that the user has the ROLE_ANONYMOUS credentials, so that is not the problem.

      After debug I found the HttpServletRequest wrapped by the SavedRequestAwareWrapper which in turn inherits the 'isUserInRole' behaviour from SecurityContextHolderAwareRequestWrapper
      However, the isUserInRole on the latter class first calls getAuthentication, this method looks like this:

      [code]
      //SecurityContextHolderAwareRequestWrapper - line 74
      private Authentication getAuthentication() {
      Authentication auth = SecurityContextHolder.getContext().getAuthentication();

      if (!authenticationTrustResolver.isAnonymous(auth))

      { return auth; }

      return null;
      }
      [/code]

      So what happens is, is that the Authentication is not returned, but null instead
      Therefore the isUserInRole returns false.

      I think this is a bug; why should isUserInRole not work when the user has the ROLE_ANONYMOUS ?

        Issue Links

          Activity

          Hide
          Luke Taylor added a comment -

          If you read the Javadoc for HttpServletRequest.isUserinRole(), it returns:

          "a boolean indicating whether the user making this request belongs to a given role; false if the user has not been authenticated".

          The wrapper is intended to mimic the API hence it returns false for an unauthenticated user.

          Show
          Luke Taylor added a comment - If you read the Javadoc for HttpServletRequest.isUserinRole(), it returns: "a boolean indicating whether the user making this request belongs to a given role; false if the user has not been authenticated". The wrapper is intended to mimic the API hence it returns false for an unauthenticated user.
          Hide
          errorken added a comment -

          I have read the javadoc, and if you interprete what the javadoc says you'll notice that the current implementation is wrong.

          The javadoc says that the method returns false if, and only if, te user is NOT authenticated and is thus NOT in role.

          If a user has been ANONYMOUSLY authenticated , the user IS authenticated and IS in a role (role_anonymous by default), do you agree on this?

          A user with role_anonymous is exactly the same as a user with for example role_admin.
          The only difference is the authentication strength, but it does not deny the fact that the user is authenticated (he is authenticated as being in role_anonymous)

          For role_admin you probably have some strongher authentication setup, such as a username/password verification.
          While for role_anonymous the authentication is less strict; it might be an email address that should have a valid form, or might be always valid if no identification is supplied.

          I'm cloning this issue since I really think the current implementation is just wrong.

          Show
          errorken added a comment - I have read the javadoc, and if you interprete what the javadoc says you'll notice that the current implementation is wrong. The javadoc says that the method returns false if, and only if, te user is NOT authenticated and is thus NOT in role. If a user has been ANONYMOUSLY authenticated , the user IS authenticated and IS in a role (role_anonymous by default), do you agree on this? A user with role_anonymous is exactly the same as a user with for example role_admin. The only difference is the authentication strength, but it does not deny the fact that the user is authenticated (he is authenticated as being in role_anonymous) For role_admin you probably have some strongher authentication setup, such as a username/password verification. While for role_anonymous the authentication is less strict; it might be an email address that should have a valid form, or might be always valid if no identification is supplied. I'm cloning this issue since I really think the current implementation is just wrong.
          Hide
          Luke Taylor added a comment -

          The servlet spec doesn't have a concept of "anonymously authenticated" and by most interpretations an anonymous user has not been authenticated. You might wish to interpret that differently, but it isn't a bug - Spring Security's AnonymousProcessingFilter was only introduced to facilitate the exclusion of specific URLs from the FilterSecurityInterceptor.

          If you want different behaviour you can use a custom wrapper class in SecurityContextHolderIntegrationFilter (or extend the existing implementation and override isUserInRole) .

          Show
          Luke Taylor added a comment - The servlet spec doesn't have a concept of "anonymously authenticated" and by most interpretations an anonymous user has not been authenticated. You might wish to interpret that differently, but it isn't a bug - Spring Security's AnonymousProcessingFilter was only introduced to facilitate the exclusion of specific URLs from the FilterSecurityInterceptor. If you want different behaviour you can use a custom wrapper class in SecurityContextHolderIntegrationFilter (or extend the existing implementation and override isUserInRole) .
          Hide
          Kristian Luck added a comment -

          I just wanted to voice my support for errorken's interpretation.

          Indeed, the servlet spec (v2.4) doesn't have a concept of 'anonymously authenticated'. In fact, it only mentions four "mechanisms" [SRV.12.5]: HTTP Basic Authentication, HTTP Digest Authentication, HTTPS Client Authentication, and Form Based Authentication.

          Out-of-the-box, Spring supports these four mechanisms plus many others. I definitely feel that if Anonymous Authentication has been explicitly configured, then the concept of "anonymously authenticated" has a definite meaning, and that meaning is in line with errorken's rationale.

          If I can offer some further persuasion to reconsider the present implementation, consider a publicly visible website such as a user forum. [Anonymous] visitors are free to browse, but may not be allowed to post until they've registered. The [Register] link could very reasonably be rendered only on condition of ROLE_ANONYMOUS. Unless "anonymous authentication" is recognized as a legitimate form of authentication, the implementation of this render condition would be different than most others on the site; for no good reason. Finally, the Spring Security Reference Documentation v2.0.x contains a chapter on Anonymous Authentication. If it's not an valid form of authentication, then why is a chapter dedicated to it?

          Show
          Kristian Luck added a comment - I just wanted to voice my support for errorken's interpretation. Indeed, the servlet spec (v2.4) doesn't have a concept of 'anonymously authenticated'. In fact, it only mentions four "mechanisms" [SRV.12.5] : HTTP Basic Authentication, HTTP Digest Authentication, HTTPS Client Authentication, and Form Based Authentication. Out-of-the-box, Spring supports these four mechanisms plus many others. I definitely feel that if Anonymous Authentication has been explicitly configured, then the concept of "anonymously authenticated" has a definite meaning, and that meaning is in line with errorken's rationale. If I can offer some further persuasion to reconsider the present implementation, consider a publicly visible website such as a user forum. [Anonymous] visitors are free to browse, but may not be allowed to post until they've registered. The [Register] link could very reasonably be rendered only on condition of ROLE_ANONYMOUS. Unless "anonymous authentication" is recognized as a legitimate form of authentication, the implementation of this render condition would be different than most others on the site; for no good reason. Finally, the Spring Security Reference Documentation v2.0.x contains a chapter on Anonymous Authentication. If it's not an valid form of authentication, then why is a chapter dedicated to it?

            People

            • Assignee:
              Luke Taylor
              Reporter:
              errorken
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: