Uploaded image for project: 'WildFly Elytron'
  1. WildFly Elytron
  2. ELY-1677

Elytron Bearer Token Authentication - Return a 401 on Invalid Token

XMLWordPrintable

      Issue
      Currently, Elytron will send back a 403 Response when an invalid bearer token is sent. For the built-in JWT validator (the token validation we are using), this includes a few checks like signature, expiration time, audience and issuer.

      It seems that the current BearerTokenAuthenticationMechanism does not differentiate between failed authentication and failed authorization, returning a 403 in both cases. This produces conflicting and erroneous results. Did I fail to authenticate (say, expired JWT) or did I authenticate but do not have access to the resource in question?

      This would also be closer in line with RFC 6750 (The OAuth 2.0 Authorization Framework: Bearer Token Usage) which includes an example of an expired (invalid) token.

      And in response to a protected resource request with an
      authentication attempt using an expired access token:

      HTTP/1.1 401 Unauthorized
      WWW-Authenticate: Bearer realm="example",
      error="invalid_token",
      error_description="The access token expired"

      Potential Solution
      Perhaps this could be ameliorated by something akin to the following change in BearerTokenAuthenticationMechanism::evaluateRequest by differentiating between failure to authorize and failure to authenticate the token. Merely a quick, unvetted example as I haven't had enough time to dig in to the source.

      if (verifyCallback.isVerified()) {
      	AuthorizeCallback authorizeCallback = new AuthorizeCallback(null, null);
      
      	handleCallback(authorizeCallback);
      
      	if (authorizeCallback.isAuthorized()) {
      	    httpBearer.debugf("Token authentication successful.");
      	    handleCallback(new IdentityCredentialCallback(new BearerTokenCredential(tokenEvidence.getToken()), true));
      	    handleCallback(AuthenticationCompleteCallback.SUCCEEDED);
      	    request.authenticationComplete();
      	    return;
      	}
      	else{
      		httpBearer.debugf("Token authorization failed message.");
      		request.authenticationFailed("Some token unauthorized message", response -> response.setStatusCode(FORBIDDEN));
      		return;
      	}  
      }
      httpBearer.debugf("Token authentication failed.");
      request.authenticationFailed("Invalid bearer token", response -> response.setStatusCode(UNAUTHORIZED));
      return;
      

              mmazanek Martin Mazánek (Inactive)
              edwardstat Edward Stathopoulos (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Created:
                Updated:
                Resolved: