> ## Documentation Index
> Fetch the complete documentation index at: https://ai.easyaf.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# AuthorizationServerMetadataClient

> Discovers an RFC 8414 authorization server metadata document (or its OpenID Connect discovery document counterpart) over the handler-free `'OAuth'` named [Ht...

## Definition

**Assembly:** Microsoft.OData.Mcp.Authentication.dll

**Namespace:** Microsoft.OData.Mcp.Authentication.Outbound

**Inheritance:** System.Object

## Syntax

```csharp theme={null}
Microsoft.OData.Mcp.Authentication.Outbound.AuthorizationServerMetadataClient
```

## Summary

Discovers an RFC 8414 authorization server metadata document (or its OpenID Connect discovery document
counterpart) over the handler-free `"OAuth"` named [HttpClient](https://learn.microsoft.com/dotnet/api/system.net.http.httpclient), probing the well-known
candidates for a base URI in the order that prefers a Microsoft identity platform v2 document over its
v1 counterpart.

## Remarks

A new `"OAuth"` client is requested from [IHttpClientFactory](https://learn.microsoft.com/dotnet/api/system.net.http.ihttpclientfactory) on every call rather than
cached, matching the "Two named HttpClients" table in `specs/v3/AUTHENTICATION.md`. Per `AUTH-14`,
an Entra-style authorization server publishes both a v1 (OpenID Connect only) and a v2 (RFC 8414 and OpenID
Connect) document at the same base URI; [Uri)](https://learn.microsoft.com/dotnet/api/microsoft.odata.mcp.authentication.outbound.authorizationservermetadataclient.candidatedocuments\(system.uri\)) orders the v2 candidates
first so discovery never selects the v1 issuer when a v2 one is available. Response bodies are never
logged.

## Examples

```csharp theme={null}
var client = new AuthorizationServerMetadataClient(httpClientFactory, logger);
var metadata = await client.DiscoverAsync(new Uri("https://login.microsoftonline.com/common"), cancellationToken);
if (metadata is not null)
{
    // metadata.TokenEndpoint is guaranteed non-null and absolute.
}
```

## Constructors

### &#x20;.ctor

Initializes a new instance of the [AuthorizationServerMetadataClient](https://ai.easyaf.dev/odata-mcp/api-reference/Microsoft/OData/Mcp/Authentication/Outbound/AuthorizationServerMetadataClient.md) class.

#### Syntax

```csharp theme={null}
public AuthorizationServerMetadataClient(System.Net.Http.IHttpClientFactory httpClientFactory, Microsoft.Extensions.Logging.ILogger<Microsoft.OData.Mcp.Authentication.Outbound.AuthorizationServerMetadataClient> logger)
```

#### Parameters

| Name | Type | Description |
| - | - | - |
| `httpClientFactory` | `System.Net.Http.IHttpClientFactory` | The factory used to create the `"OAuth"` named client per call. |
| `logger` | `Microsoft.Extensions.Logging.ILogger<Microsoft.OData.Mcp.Authentication.Outbound.AuthorizationServerMetadataClient>` | The logger this instance records non-fatal well-known outcomes and probe attempts to. |

#### Exceptions

| Exception | Description |
| - | - |
| `ArgumentNullException` | Thrown when *httpClientFactory* or *logger* is [`null`](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null). |

### &#x20;.ctor Inherited

> [!NOTE]
>
> Inherited from `object`

#### Syntax

```csharp theme={null}
public Object()
```

## Methods

### &#x20;CandidateDocuments

Builds the well-known authorization server metadata candidates for a base URI, in probe order.

#### Syntax

```csharp theme={null}
public static System.Collections.Generic.IReadOnlyList<System.Uri> CandidateDocuments(System.Uri baseUri)
```

#### Parameters

| Name | Type | Description |
| - | - | - |
| `baseUri` | `System.Uri` | The absolute authorization server base URI, such as an issuer or an authorization endpoint's origin and path. |

#### Returns

Type: `System.Collections.Generic.IReadOnlyList<System.Uri>`
Five candidates when *baseUri* carries a path beyond `/`: the versioned (v2)
RFC 8414 document, the versioned OpenID Connect document, the unversioned RFC 8414 document, the RFC
8414 §3.1 path-prefixed document, and the unversioned OpenID Connect document, in that order. The
path-prefixed candidate is omitted, leaving four candidates, when *baseUri* has no
path beyond `/`.

#### Exceptions

| Exception | Description |
| - | - |
| `ArgumentNullException` | Thrown when *baseUri* is [`null`](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null). |
| `ArgumentException` | Thrown when *baseUri* is not an absolute URI. |

#### Remarks

A trailing `/` on *baseUri* is trimmed before any suffix is appended, so no
candidate carries a doubled path separator. The versioned candidates are listed first so that an
Entra-style authorization server, which publishes a v1 (OpenID Connect only) document at the
unversioned base and a v2 (RFC 8414 and OpenID Connect) document under `/v2.0`, is discovered
through its v2 issuer.

### &#x20;DiscoverAsync

Probes [Uri)](https://learn.microsoft.com/dotnet/api/microsoft.odata.mcp.authentication.outbound.authorizationservermetadataclient.candidatedocuments\(system.uri\)) in order and returns the first candidate that resolves to
a usable metadata document.

#### Syntax

```csharp theme={null}
public System.Threading.Tasks.Task<Microsoft.OData.Mcp.Authentication.Outbound.AuthorizationServerMetadata> DiscoverAsync(System.Uri baseUri, System.Threading.CancellationToken cancellationToken)
```

#### Parameters

| Name | Type | Description |
| - | - | - |
| `baseUri` | `System.Uri` | The absolute authorization server base URI to discover metadata for. |
| `cancellationToken` | `System.Threading.CancellationToken` | The token that cancels the request. |

#### Returns

Type: `System.Threading.Tasks.Task<Microsoft.OData.Mcp.Authentication.Outbound.AuthorizationServerMetadata?>`
The first candidate's parsed document, or [`null`](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null) when every candidate is non-fatally
unusable (missing, unparseable, or lacking a `token_endpoint`).

#### Exceptions

| Exception | Description |
| - | - |
| `ArgumentNullException` | Thrown when *baseUri* is [`null`](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null). |
| `ArgumentException` | Thrown when *baseUri* is not an absolute URI. |
| `OutboundDiscoveryException` | Thrown when a probe times out, fails at the transport, or returns a 5xx status, after one retry. |

#### Examples

```csharp theme={null}
var metadata = await client.DiscoverAsync(new Uri("https://login.microsoftonline.com/common"), cancellationToken);
```

#### Remarks

Every probe is attempted over `http` only when its host is loopback; discovery stops at the first
candidate with a `token_endpoint`, so a later candidate (such as the legacy v1 document) is never
requested once an earlier one has already succeeded.

### &#x20;Equals Inherited Virtual

> [!NOTE]
>
> Inherited from `object`

#### Syntax

```csharp theme={null}
public virtual bool Equals(object obj)
```

#### Parameters

| Name | Type | Description |
| - | - | - |
| `obj` | `object?` | - |

#### Returns

Type: `bool`

### &#x20;Equals Inherited

> [!NOTE]
>
> Inherited from `object`

#### Syntax

```csharp theme={null}
public static bool Equals(object objA, object objB)
```

#### Parameters

| Name | Type | Description |
| - | - | - |
| `objA` | `object?` | - |
| `objB` | `object?` | - |

#### Returns

Type: `bool`

### &#x20;GetHashCode Inherited Virtual

> [!NOTE]
>
> Inherited from `object`

#### Syntax

```csharp theme={null}
public virtual int GetHashCode()
```

#### Returns

Type: `int`

### &#x20;GetType Inherited

> [!NOTE]
>
> Inherited from `object`

#### Syntax

```csharp theme={null}
public System.Type GetType()
```

#### Returns

Type: `System.Type`

### &#x20;MemberwiseClone Inherited

> [!NOTE]
>
> Inherited from `object`

#### Syntax

```csharp theme={null}
protected internal object MemberwiseClone()
```

#### Returns

Type: `object`

### &#x20;ReferenceEquals Inherited

> [!NOTE]
>
> Inherited from `object`

#### Syntax

```csharp theme={null}
public static bool ReferenceEquals(object objA, object objB)
```

#### Parameters

| Name | Type | Description |
| - | - | - |
| `objA` | `object?` | - |
| `objB` | `object?` | - |

#### Returns

Type: `bool`

### &#x20;ToString Inherited Virtual

> [!NOTE]
>
> Inherited from `object`

#### Syntax

```csharp theme={null}
public virtual string ToString()
```

#### Returns

Type: `string?`

### &#x20;TryGetAsync

Attempts to fetch and parse the authorization server metadata document at a well-known URL.

#### Syntax

```csharp theme={null}
public System.Threading.Tasks.Task<Microsoft.OData.Mcp.Authentication.Outbound.AuthorizationServerMetadata> TryGetAsync(System.Uri url, System.Threading.CancellationToken cancellationToken)
```

#### Parameters

| Name | Type | Description |
| - | - | - |
| `url` | `System.Uri` | The absolute authorization server metadata URL. |
| `cancellationToken` | `System.Threading.CancellationToken` | The token that cancels the request. |

#### Returns

Type: `System.Threading.Tasks.Task<Microsoft.OData.Mcp.Authentication.Outbound.AuthorizationServerMetadata?>`
The parsed document on a `200` response with a well-formed body carrying an absolute
`token_endpoint`; otherwise [`null`](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null) after a 401, 403, 404, unparseable body, a
document without a usable `token_endpoint`, or any other non-retryable non-success status.

#### Exceptions

| Exception | Description |
| - | - |
| `ArgumentNullException` | Thrown when *url* is [`null`](https://learn.microsoft.com/dotnet/csharp/language-reference/keywords/null). |
| `ArgumentException` | Thrown when *url* is not an absolute URI, or is an `http` URI whose host is not loopback. |
| `OutboundDiscoveryException` | Thrown when the request times out, fails at the transport, or returns a 5xx status, after one retry. |

#### Examples

```csharp theme={null}
var metadata = await client.TryGetAsync(new Uri("https://login.microsoftonline.com/common/v2.0/.well-known/oauth-authorization-server"), cancellationToken);
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.