Introspection of an access token
Identity Server 4 is an OpenID Connect and OAuth 2.0 Framework. On this post I am going to dive into the introspection of reference access token.
When using reference tokens - IdentityServer will store the contents of the token in a data store and will only issue a unique identifier for this token back to the client. The API receiving this reference must then open a back-channel communication to IdentityServer to validate the token. Identity server 4 documentation
Identity server has an introspection endpoint is used in order to validate a reference token.
Identity Server provides two middlewares:OAuth2Introspection(used only for the validation of reference tokens) and AccessTokenValidation (used for validation both of reference token and jwt).
Requirements
- Have Identity Server 4 set up
- Postman
- .Net core 1.1
Postman
Obtain the configuration from the discovery endpoint by using the following link
http://address:port/core/.well-known/openid-configuration
. The introspection endpoint is on my case:http://localhost:50774/connect/introspect
.Obtain an access token from the
http://localhost:50774/connect/token
(See the image bellow)Copy the value of the
access_token
.
4.
- Open a new tab , switch to POST and paste the introspection endpoint adress.
- Click on the Body, select x-www-form-urlencoded or form-data. Add a new key with name
token
and its value field paste the copied access token from the previous step.
- Click on the Headers. Add new key with name
Authorization
. Regarding its value:
On the authority server I have defined the api resource :
return new List<ApiResource>
{
new ApiResource
{
Name = "api1",
DisplayName = "My API",
Scopes = new List<Scope>
{
new Scope
{
Name = "api1",
DisplayName = "api1 scope",
Emphasize = true,
ShowInDiscoveryDocument = false,
UserClaims = new List<string>
{
"name"
}
}
},
ApiSecrets = new List<Secret>
{
new Secret("secret".Sha256())
}
}
};
Therefore the value should be : Basic YXBpMTpzZWNyZXQ=
.
The “YXBpMTpzZWNyZXQ=” is a base64 string of the convertion of the string api1:secret
.
The response should look like this in case it’s valid:
and if it’s not valid:
.Net Core Console app
I created a core console app. I can get the same result from console app by providing the authority address, the scope name and the scope secret( For more info ). I have also implemented a command that validates a token wihtout connecting to the introspection endpoint. (This is work in progress and I have tested it only with tokens that were grant type of password).
dotnet run validate serverAuthorityAddress scopeName scopePassword accessToken userId expiresIn clientId
I created this command to quick validate a token without the need to have a server running.For example I provided an access token that was created by another authority server(identity server as well) and I ran my tool.
Result:
Manual Validation
Claims:
{
"nbf": 1500622663,
"exp": 1500623023,
"iss": "http://localhost:50774",
"aud": [
"http://localhost:50774/resources",
"api1"
],
"client_id": "android",
"sub": "ec540763-2732-47c0-b73e-e228059ea2c8",
"auth_time": 1500622663,
"idp": "local",
"name": "leo",
"amr": "pwd",
"scope": "api1",
"active": true
}
iss : the expected value should be the address of the authority server(in my case http://localhost:50774
. If not, the access token is invalid.
nbf and exp : check if the token is not expired and yet valid. Compare it with “auth_time” as well.
aud : if it’s targetting the correct audience and scope
If I sent invalid token, the response would contain only the “active” property(like in the previous image).
At this point I could check and validate more properties such as sub :if the uid matches with the user id, etc.
What about mobiles?
The following libraries can be used in order to communicate with identity server or any openid and oauth authority server. iOS and Android
On one of my following post I am going to write about how to validate access tokens in mobiles.