Wednesday, January 24, 2018

Authentication and Permission Requirements in WSO2 OAuth 2.0 Token Introspection API


WSO2 Identity Server provides an API for OAuth 2.0 Token Introspection (see spec [1] for more information) for authorized parties to query the metadata of the access tokens it has issued. For knowing more information on the API requests, you can refer the official documentation in [2]. The main focus of this blog post is to discuss the authentication and required permissions for invoking this API by external parties.


Required Permission for Invoking the API

By default, the OAuth Token Introspection API of WSO2 Identity Server is protected where it requires authentication and also users should be authorized (needs a particular permission) to invoke the API. This is due to following reasons as per the specification [1].

   To prevent token scanning attacks, the endpoint MUST also require
   some form of authorization to access this endpoint, such as client
   authentication as described in OAuth 2.0 [RFC6749] or a separate
   OAuth 2.0 access token such as the bearer token

   If left unprotected and un-throttled, the introspection endpoint
   could present a means for an attacker to poll a series of possible
   token values, fishing for a valid token.  To prevent this, the
   authorization server MUST require authentication of protected
   resources that need to access the introspection endpoint and SHOULD
   require protected resources to be specifically authorized to call the
   introspection endpoint.

So, this required level of permission is defined in <IS_HOME>/repository/conf/identity/identity.xml file. It has following by default.



<ResourceAccessControl>
.....
     <Resource context="(.*)/oauth2/introspect(.*)" http-method="all" secured="true">
         <Permissions>/permission/admin/manage/identity/applicationmgt/view</Permissions>
     </Resource>


So, for invoking this API, the user/client should have the above permission. What you can do is, create a role in Identity Server granting this particular permission (shown in image below) and assign the role to the users who needs to invoke this API.


By modifying the particular <Permissions> element value in the identity.xml file for this, you can lower or raise the required level of permission.


Removing Authentication from Token Introspection API

In case you need to remove the authentication enforcement of this endpoint, what you can do is, modify the identity.xml file and delete/comment the following section.



<Resource context="(.*)/oauth2/introspect(.*)" http-method="all" secured="true">
         <Permissions>/permission/admin/manage/identity/applicationmgt/view</Permissions>
     </Resource>


This will remove the authentication enforcement where any user can invoke the Token Introspection API without providing user credentials or OAuth bearer token.

Sample request is below.

curl -v -k -H 'Content-Type: application/x-www-form-urlencoded' -X POST --data 'token=XXXXXXXXXXX' https://localhost:9443/oauth2/introspect


Invoking the API with Basic Authentication

If you are testing this with curl, you can include the user’s credential in -u parameter as shown below and invoke the API.

curl -v -k -u <username>:<password> -H 'Content-Type: application/x-www-form-urlencoded' -X POST --data 'token=XXXXXXXX' https://localhost:9443/oauth2/introspect

Also, you can send the user credentials in the Authorization header as well. You need to prepare a string like <username>:<password> and then base64 encode the string and put in the Authorization header value after Basic.


curl -v -k -H 'Authorization: Basic XXXXX' -H 'Content-Type: application/x-www-form-urlencoded' -X POST --data 'token=xxxxxxxxxxxxxxxxx' https://localhost:9443/oauth2/introspect

Note: In OAuth APIs, for token requests, you use ClientID:ClientSecret base64 encoded string in the Authorization header for basic authentication. However for Token Introspection API, that is not supported. For basic authentication, you must use user credentials.


Invoking the API with OAuth Bearer Token for Authentication

For invoking the Token Introspection API, instead of using user credentials (basic authentication), you can use OAuth access tokens. For that, first you need to obtain an OAuth access token from Identity Server and include it in the Authorization header value after Bearer. The token sent in the body is the access token to be validated.


curl -v -k -H 'Authorization: Bearer XXXXX' -H 'Content-Type: application/x-www-form-urlencoded' -X POST --data 'token=xxxxxxxxxxxxxxxxxxx' https://localhost:9443/oauth2/introspect


IMPORTANT: When you are using OAuth access tokens for invoking the API, if the token is obtained through authorization_code, implicit or password grant types, then the user account associated with the access token should have the required permission (defined in identity.xml file). If the access token is obtained through client_credentials grant type, then the user who registered the OAuth application should have the particular required permission.


Error Responses

  • 403: Forbidden

If we use OAuth bearer token for authenticating to the API, if the token’s associated user does not have required permission, then server will give 403: Forbidden response. Also we’ll get the token’s associated user’s username in WWW-Authenticate response header. The response is same even if we use basic authentication when the user does not have the required permission.



  • 401: Unauthorized

When basic authentication is used to authenticate to the Token Introspection API, if the user’s credentials are incorrect, the server will respond with 401 Unauthorized HTTP status code. In the WWW-Authenticate response header, it will return whatever the username we sent in the request (regardless it’s a valid username).




References

[1] https://tools.ietf.org/html/rfc7662
[2] https://docs.wso2.com/display/IS540/Invoke+the+OAuth+Introspection+Endpoint


Tharindu Edirisinghe
Platform Security Team
WSO2