Edit

Authenticate users and acquire tokens for interactive agents

Interactive agents take actions on behalf of users. To act on behalf of users securely, the agent authenticates the user, gets consent for required permissions, and acquires access tokens for downstream APIs. This article walks you through the end-to-end authentication and token acquisition flow for your interactive agent:

  1. Register a redirect URI for your agent identity blueprint.
  2. Configure user or admin authorization (consent).
  3. Authenticate the user and obtain an access token.
  4. Validate the token and extract user claims.
  5. Acquire tokens for downstream APIs using the On-Behalf-Of (OBO) flow.

Note

This article covers interactive agents that act on behalf of signed-in users using the OBO flow. If your agent needs its own user-like identity (a digital worker scenario), see Agent's user accounts and Agent's user account OAuth flow.

Prerequisites

Before you begin, ensure you have:

  • An agent identity blueprint. Record the agent identity blueprint app ID (client ID).
  • An agent identity.
  • A client application registered in Microsoft Entra to handle user authentication.
  • Familiarity with the OAuth 2.0 authorization code flow.
  • The ability to run an ASP.NET Core web API if you plan to use the token validation and OBO samples in this article.

For admin authorization, you also need:

Register a redirect URI

To support delegated permissions, your agent identity blueprint must be configured with a valid redirect URI. This URI is where Microsoft Entra ID sends users after they grant or deny consent to your agent.

To update the redirect URI on the agent identity blueprint, you first need to obtain an access token with the delegated permission AgentIdentityBlueprint.ReadWrite.All. Then send a PATCH request to the application object for the agent identity blueprint:

PATCH https://graph.microsoft.com/beta/applications/<agent-blueprint-id>
OData-Version: 4.0
Content-Type: application/json
Authorization: Bearer <token>

{
  "web": {
    "redirectUris": [
      "https://myagentapp.com/authorize"
    ]
  }
}

Configure user authorization

Before the agent can act on behalf of a user, the user must consent to the required permissions. The user consent request doesn't return a token. Instead, it records that the user granted the agent permission to act on their behalf. Token acquisition happens in Authenticate the user and request a token.

Important

Use the agent identity client ID in the client_id parameter, not the agent identity blueprint ID.

To prompt a user for consent, construct an authorization URL and redirect the user to it. The agent can present this URL in different ways, for example, as a link in a chat message.

https://login.microsoftonline.com/contoso.onmicrosoft.com/oauth2/v2.0/authorize?
  client_id=<agent-identity-id>
  &response_type=none
  &redirect_uri=https%3A%2F%2Fmyagentapp.com%2Fauthorize
  &response_mode=query
  &scope=User.Read
  &state=xyz123

When the user opens this URL, Microsoft Entra ID prompts them to sign in and grant consent. After consent, the user is sent back to the redirect URI.

The key parameters in the user consent authorization URL are:

  • client_id: The agent identity client ID (not the agent identity blueprint client ID).
  • response_type: Set to none because this request records consent only. Token acquisition uses response_type=code in Authenticate the user and request a token.
  • redirect_uri: Must match exactly the redirect URI configured on the agent identity blueprint.
  • scope: Specify the delegated permissions you need (for example, User.Read).
  • state: Optional parameter for maintaining state between the request and callback.

For more information on OAuth authorization concepts, see Permissions and consent in the Microsoft identity platform.

Configure admin authorization

An administrator in Microsoft Entra ID can grant consent to the agent for all users in the tenant. Use admin consent when you need application permissions, because individual users can't consent to them.

To grant tenant-wide admin consent, direct an administrator to the following URL. Use the agent identity ID in the client_id parameter.

https://login.microsoftonline.com/contoso.onmicrosoft.com/v2.0/adminconsent
?client_id=<agent-identity-id>
&scope=User.Read
&redirect_uri=https://entra.microsoft.com/TokenAuthorize
&state=xyz123

After the administrator grants consent, the permissions apply to the whole tenant. Users don't need to consent again.

Authenticate the user and request a token

After authorization is configured, the client app (such as a frontend or mobile app) starts an OAuth 2.0 authorization code request. The token audience is the agent identity blueprint. In the authorization code request, client_id refers to the client app's own registered application ID, not the agent identity or agent identity blueprint ID.

  1. Redirect the user to the Microsoft Entra ID authorization endpoint with the following parameters:

    GET https://login.microsoftonline.com/<my-test-tenant>/oauth2/v2.0/authorize?client_id=<client-app-id>
    &response_type=code
    &redirect_uri=<redirect_uri>
    &response_mode=query
    &scope=api://<agent-blueprint-id>/access_agent
    &state=abc123
    
  2. After the user signs in, your app receives an authorization code at the redirect URI. Exchange the authorization code for an access token:

    POST https://login.microsoftonline.com/<my-test-tenant>/oauth2/v2.0/token
    Content-Type: application/x-www-form-urlencoded
    
    client_id=<client-app-id>
    &grant_type=authorization_code
    &code=<authorization_code>
    &redirect_uri=<redirect_uri>
    &scope=api://<agent-blueprint-id>/access_agent
    &client_secret=<client-secret>
    

    Include the client_secret parameter only if using a confidential client.

    The JSON response contains an access token that can be used to access the agent's API.

Validate the access token

The web API must validate the incoming access token before the agent can act. Always use an approved library to validate tokens. Don't write your own token validation code.

  1. Install the Microsoft.Identity.Web NuGet package:

    dotnet add package Microsoft.Identity.Web
    
  2. In your ASP.NET Core web API project, implement Microsoft Entra ID authentication:

    // Program.cs
    using Microsoft.Identity.Web;
    
    var builder = WebApplication.CreateBuilder(args);
    
    builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
    
    var app = builder.Build();
    
    app.UseAuthentication();
    app.UseAuthorization();
    
  3. Configure authentication credentials in the appsettings.json file:

    Warning

    Client secrets shouldn't be used as client credentials in production environments for agent identity blueprints due to security risks. Instead, use more secure authentication methods such as federated identity credentials (FIC) with managed identities or client certificates. These methods provide enhanced security by eliminating the need to store sensitive secrets directly within your application configuration.

    "AzureAd": {
        "Instance": "https://login.microsoftonline.com/",
        "TenantId": "<my-test-tenant>",
        "ClientId": "<agent-blueprint-id>",
        "Audience": "<agent-blueprint-id>",
        "ClientCredentials": [
            {
                "SourceType": "ClientSecret",
                "ClientSecret": "your-client-secret"
            }
        ]
    }
    

For more information about Microsoft.Identity.Web, see Microsoft.Identity.Web documentation.

Validate user claims

After access token validation, the agent can identify the user and perform authorization checks. The following example API route extracts user claims from the access token and returns them in the API response:

app.MapGet("/hello-agent", (HttpContext httpContext) =>
{   
    var claims = httpContext.User.Claims.Select(c => new
    {
        Type = c.Type,
        Value = c.Value
    });

    return Results.Ok(claims);
})
.RequireAuthorization();

Acquire tokens for downstream APIs

After an interactive agent validates the user's token, it can request access tokens to call downstream APIs on behalf of the user. The On-Behalf-Of (OBO) flow allows the agent to:

  • Receive an access token from a client.
  • Exchange it for a new access token for a downstream API like Microsoft Graph.
  • Use that new token to access protected resources on behalf of the original user.

The Microsoft.Identity.Web library simplifies the OBO implementation by handling token exchange automatically, so you don't have to manually implement the flow by following the protocol.

  1. Install the required NuGet packages:

    dotnet add package Microsoft.Identity.Web
    dotnet add package Microsoft.Identity.Web.AgentIdentities
    
  2. In your ASP.NET Core web API project, update the Microsoft Entra ID authentication implementation:

    // Program.cs
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.Identity.Abstractions;
    using Microsoft.Identity.Web;
    using Microsoft.Identity.Web.Resource;
    using Microsoft.Identity.Web.TokenCacheProviders.InMemory;
    
    var builder = WebApplication.CreateBuilder(args);
    
    builder.Services.AddMicrosoftIdentityWebApiAuthentication(builder.Configuration)
        .EnableTokenAcquisitionToCallDownstreamApi();
    builder.Services.AddAgentIdentities();
    builder.Services.AddInMemoryTokenCaches();
    
    var app = builder.Build();
    
    app.UseAuthentication();
    app.UseAuthorization();
    
    app.Run();
    
  3. In the agent API, exchange the incoming user access token for a new access token for the agent identity. Microsoft.Identity.Web validates the incoming access token and handles the on-behalf-of token exchange:

    app.MapGet("/agent-obo-user", async (HttpContext httpContext) =>
    {
        string agentIdentity = "<your-agent-identity>";
        IAuthorizationHeaderProvider authorizationHeaderProvider = httpContext.RequestServices.GetService<IAuthorizationHeaderProvider>()!;
        AuthorizationHeaderProviderOptions options = new AuthorizationHeaderProviderOptions().WithAgentIdentity(agentIdentity);
    
        string authorizationHeaderWithUserToken = await authorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(["https://graph.microsoft.com/.default"], options);
    
        var response = new { header = authorizationHeaderWithUserToken };
        return Results.Json(response);
    })
    .RequireAuthorization();
    

Under the hood, the OBO flow involves two token exchanges: first, the agent identity blueprint obtains an exchange token using its client credential, and then the agent identity exchanges that token along with the user's access token for a downstream API token. For the full protocol walkthrough, including HTTP request formats and token validation details, see On-behalf-of flow in agents.

Learn more about agent tokens and related APIs: