|
| 1 | +--- |
| 2 | +title: Token Introspection Endpoint |
| 3 | +description: Learn how to use the OAuth 2.0 token introspection endpoint to validate and inspect access tokens using HttpClient extensions. |
| 4 | +sidebar: |
| 5 | + order: 4 |
| 6 | + label: Token Introspection |
| 7 | + badge: |
| 8 | + text: v7.1 |
| 9 | + variant: tip |
| 10 | +redirect_from: |
| 11 | + - /foss/identitymodel/endpoints/introspection/ |
| 12 | +--- |
| 13 | + |
| 14 | +import { Code } from "astro/components"; |
| 15 | +import { Tabs, TabItem } from "@astrojs/starlight/components"; |
| 16 | + |
| 17 | +The client library for [OAuth 2.0 token introspection (RFC 7662)](https://tools.ietf.org/html/rfc7662) is provided by the `IntrospectionClient` class, |
| 18 | +and as an extension method for `HttpClient`. |
| 19 | + |
| 20 | +## Token Introspection Request |
| 21 | + |
| 22 | +The following code sends a reference token to an introspection endpoint: |
| 23 | + |
| 24 | +{/* prettier-ignore */} |
| 25 | +<Tabs> |
| 26 | + <TabItem label="Using IntrospectionClient"> |
| 27 | + <Code |
| 28 | + lang="csharp" |
| 29 | + code={`var clientOptions = new IntrospectionClientOptions |
| 30 | +{ |
| 31 | + Address = Endpoint, |
| 32 | + ClientId = "client", |
| 33 | + ClientSecret = "secret", |
| 34 | + ResponseFormat = ResponseFormat.Jwt, |
| 35 | +
|
| 36 | + // Optional |
| 37 | + JwtResponseValidator = new CustomIntrospectionJwtResponseValidator() |
| 38 | +}; |
| 39 | +
|
| 40 | +var httpClient = new HttpClient() |
| 41 | +{ |
| 42 | + BaseAddress = new Uri(Endpoint) |
| 43 | +}; |
| 44 | +
|
| 45 | +var introspectionClient = new IntrospectionClient(httpClient, clientOptions); |
| 46 | +var introspectionResponse = await introspectionClient.Introspect("token");`} |
| 47 | + /> |
| 48 | + </TabItem> |
| 49 | + <TabItem label="Using HttpClient extension"> |
| 50 | + <Code |
| 51 | + lang="csharp" |
| 52 | + code={`var client = new HttpClient(); |
| 53 | +var introspectionResponse = await client.IntrospectTokenAsync(new TokenIntrospectionRequest |
| 54 | +{ |
| 55 | + Address = Endpoint, |
| 56 | + Token = "token", |
| 57 | + ResponseFormat = ResponseFormat.Jwt, |
| 58 | +
|
| 59 | + // Optional |
| 60 | + JwtResponseValidator = new CustomIntrospectionJwtResponseValidator() |
| 61 | +});`} |
| 62 | + /> |
| 63 | + </TabItem> |
| 64 | +</Tabs> |
| 65 | + |
| 66 | +## Token Introspection Response |
| 67 | + |
| 68 | +The response is of type `TokenIntrospectionResponse`. Before using the response, you should always check the `IsError` |
| 69 | +property to make sure the request was successful: |
| 70 | + |
| 71 | +```csharp |
| 72 | +if (introspectionResponse.IsError) throw new Exception(introspectionResponse.Error); |
| 73 | + |
| 74 | +var isActive = introspectionResponse.IsActive; |
| 75 | +var claims = introspectionResponse.Claims; |
| 76 | +``` |
| 77 | + |
| 78 | +The `TokenIntrospectionResponse` class exposes the raw response through its `Raw` property, |
| 79 | +and to the parsed JSON document through its `Json` property. |
| 80 | +In addition, it provides access to the following standard response parameters: |
| 81 | + |
| 82 | +| Property | Value | |
| 83 | +|--------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |
| 84 | +| `Scopes` | The list of scopes associated to the token or an empty array if no `scope` claim is present. | |
| 85 | +| `ClientId` | The client identifier for the OAuth 2.0 client that requested the token or `null` if the `client_id` claim is missing. | |
| 86 | +| `UserName` | The human-readable identifier for the resource owner who authorized the token or `null` if the `username` claim is missing. | |
| 87 | +| `TokenType` | The type of the token as defined in [section 5.1 of OAuth 2.0 (RFC6749)](https://datatracker.ietf.org/doc/html/rfc6749#section-5.1) or `null` if the `token_type` claim is missing. | |
| 88 | +| `Expiration` | The expiration time of the token or `null` if the `exp` claim is missing. | |
| 89 | +| `IssuedAt` | The issuance time of the token or `null` if the `iat` claim is missing. | |
| 90 | +| `NotBefore` | The validity start time of the token or `null` if the `nbf` claim is missing. | |
| 91 | +| `Subject` | The subject of the token or `null` if the `sub` claim is missing. | |
| 92 | +| `Audiences` | The service-specific list of string identifiers representing the intended audience for the token or an empty array if no `aud` claim is present. | |
| 93 | +| `Issuer` | The string representing the issuer of the token or `null` if the `iss` claim is missing. | |
| 94 | +| `JwtId` | The string identifier for the token or `null` if the `jti` claim is missing. | |
| 95 | + |
| 96 | +## JWT Response Validation :badge[v7.1] |
| 97 | + |
| 98 | +By default, **no** validation is performed on the incoming JWT response, it is only checked for valid JWT formatting. |
| 99 | + |
| 100 | +An extensibility point is available to provide your own implementation of `ITokenIntrospectionJwtResponseValidator` using the `TokenIntrospectionRequest.JwtResponseValidator` property or using `IntrospectionClientOptions`. |
| 101 | + |
| 102 | +```csharp |
| 103 | +// ITokenIntrospectionJwtResponseValidator.cs |
| 104 | +public interface ITokenIntrospectionJwtResponseValidator |
| 105 | +{ |
| 106 | + void Validate(string rawJwtResponse); |
| 107 | +} |
| 108 | +``` |
0 commit comments