Token introspection
An API that receives an access token asks the server whether it is active and what it says. The API authenticates as itself — the demo host's api-resource, with its API secret — and may read only tokens addressed to it: the same question from another API (reports-resource) is answered active: false, which is also the whole answer for a token that has expired, been revoked or never existed.
Follows: RFC 7662.
Recorded from the demo host (src/Fdyay.IdentityServer.Host) by the IntrospectionFlow test on every CI run. A value in braces, such as {access_token_1}, is one that differs on every run; the same placeholder is the same value wherever it appears. See how these pages are made.
sequenceDiagram
participant Client
participant AuthorizationServer as Authorization Server
participant API
participant ReportsAPI as Reports API
Client->>AuthorizationServer: POST /connect/token
AuthorizationServer-->>Client: 200 OK
API->>AuthorizationServer: POST /connect/introspect
AuthorizationServer-->>API: 200 OK
ReportsAPI->>AuthorizationServer: POST /connect/introspect
AuthorizationServer-->>ReportsAPI: 200 OK
1. The client gets a token for the API
The machine client, by client credentials, for api.
Client → Authorization Server
POST /connect/token HTTP/1.1
Authorization: Basic bWFjaGluZTpzZWNyZXQ=
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
&scope=api
Authorization Server → Client
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Cache-Control: no-store, no-cache, max-age=0
Pragma: no-cache
{
"access_token": "{access_token_1}",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "api"
}
{access_token_1} decoded — the header, then the payload; the signature is not shown:
{
"alg": "RS256",
"kid": "{key_id_1}",
"typ": "at+jwt"
}
{
"aud": [
"api-resource"
],
"iss": "http://localhost",
"iat": {iat},
"nbf": {iat},
"exp": {iat + 3600},
"jti": "{jti_1}",
"client_id": "machine",
"scope": "api"
}
2. The API introspects the token it was sent
API → Authorization Server
POST /connect/introspect HTTP/1.1
Authorization: Basic YXBpLXJlc291cmNlOmFwaS1zZWNyZXQ=
Content-Type: application/x-www-form-urlencoded
token={access_token_1}
&token_type_hint=access_token
Authorization Server → API
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Cache-Control: no-store, no-cache, max-age=0
Pragma: no-cache
{
"active": true,
"iss": "http://localhost",
"iat": {iat},
"nbf": {iat},
"exp": {iat + 3600},
"jti": "{jti_1}",
"client_id": "machine",
"scope": "api",
"aud": "api-resource"
}
3. Another API asks about the same token
It is not addressed to reports-resource, so that API learns nothing.
Reports API → Authorization Server
POST /connect/introspect HTTP/1.1
Authorization: Basic cmVwb3J0cy1yZXNvdXJjZTpyZXBvcnRzLXNlY3JldA==
Content-Type: application/x-www-form-urlencoded
token={access_token_1}
Authorization Server → Reports API
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Cache-Control: no-store, no-cache, max-age=0
Pragma: no-cache
{
"active": false
}