Skip to content

Latest commit

 

History

History

web-api-obo-user

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
languages page_type name description products urlFragment
csharp
sample
ASP.NET Core minimal web API that both protects its own endpoints and accesses Microsoft Graph.
This ASP.NET Core minimal web API protects an API endpoint that access on behalf of the user another protected API. The code in this sample is used by one or more articles on docs.microsoft.com.
azure
entra-id
ms-graph
ms-identity-docs-code-obo-user-csharp

ASP.NET Core minimal web API | web api | access control (protected routes), protected web API access (Microsoft Graph) | Microsoft identity platform

This ASP.NET Core minimal web API uses the Microsoft identity platform to protect an endpoint (require authorized access), and also accesses Microsoft Graph on behalf of the user. The API uses ASP.NET Core Identity interacting with the Microsoft Authentication Library (MSAL) to protect its endpoint.

$ curl https://localhost:5001/api/me -H "Authorization: Bearer {valid-access-token}"
{
  "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users/$entity",
  "businessPhones": [],
  "displayName": "Maui",
  "givenName": null,
  "jobTitle": "dev",
  "mail": null,
  "mobilePhone": null,
  "officeLocation": null,
  "preferredLanguage": null,
  "surname": null,
  "id": "00aa11bb-cc22-dd33-ee44-ff55ee66dd77"
}

📃 This sample application backs one or more technical articles on docs.microsoft.com.

Prerequisites

Setup

1. Register the web API application in Microsoft Entra ID

First, complete the steps in Configure an application to expose a web API to register the sample API and expose a scope.

Use the following settings for your app registration:

App registration
setting
Value for this sample app Notes
Name active-directory-protected-api-access-protected-api Suggested value for this sample.
You can change the app name at any time.
Supported account types Accounts in this organizational directory only (Single tenant) Required for this sample.
Support for the Single tenant.
Identifier URI api://{clientId} Suggested value for this sample.
You must change the client id using the Value shown in Azure portal.
Expose an API Scope name: user_impersonation
Who can consent?: Admins and users
Admin consent display name: Act on behalf of the user
Admin consent description: Allows the API to act on behalf of the user.
User consent display name: Act on your behalf
User consent description: Allows the API to act on your behalf.
State: Enabled
Add a new scope that reads as follows api://{clientId}/user_impersonation. Required value for this sample.
API Permissions https://graph.microsoft.com/User.Read Add a new delegated permission for Microsoft Graph User.Read. Required value for this sample.
Client secret Value shown in Azure portal ⚠️ Record this value immediately!
It's shown only once (when you create it).

ℹ️ Bold text in the table matches (or is similar to) a UI element in the Azure portal, while code formatting indicates a value you enter into a text box or select in the Azure portal.

2. Register a client application in Microsoft Entra ID

Second, complete the steps in Register an application with the Microsoft identity platform to register the client sample app.

Use the following settings for your app registration:

App registration
setting
Value for this sample app Notes
Name active-directory-curl-app Suggested value for this sample.
You can change the app name at any time.
Supported account types Accounts in this organizational directory only (Single tenant) Required for this sample.
Support for the Single tenant.
Platform type Web Required value for this sample.
Enables the required and optional settings for the app type.
API Permissions api://{clientId}/user_impersonation Add a delegated type permission by searching within the APIs using the new Application (client) ID from the previous step. Then select the user_impersonation. Required value for this sample.
Client secret Value shown in Azure portal ⚠️ Record this value immediately!
It's shown only once (when you create it).

ℹ️ Bold text in the table matches (or is similar to) a UI element in the Azure portal, while code formatting indicates a value you enter into a text box or select in the Azure portal.

3. Go back to the recently registered web API application

Third, modify the web API application to update the following settings to reference the cUrl app

App registration
setting
Value for this sample app Notes
knownClientApplications Client ID (UUID) of the application created in step 2. Required value for this sample.

4. Configure the web API

  1. Open the protected-api-access-protected-api/appsettings.json file in your code editor and modify the following code:

    "ClientId": "Enter_the_Application_Id_here",
    "TenantId": "Enter_the_Tenant_Info_here",
    "ClientSecret": "Enter_the_Client_Secret_here"

Run the application

1. Run the web API

Execute the following command to get the app up and running:

dotnet run

2. Send request to the web API

  1. Once the web API is listening, execute the following to send a request to its protected endpoint.

    curl -X GET https://localhost:5001/api/me -ki

    ℹ️ The expected response is 401 Unauthorized because you've sent a request to the protected endpoint without including an access token (as a bearer token).

  2. Use Postman, curl, or similar to send an HTTP GET request to https://localhost:5001/me, this time including an Authorization header of Bearer {valid-access-token}.

    If everything worked, your protected web API should return a response similar to this:

    curl -X GET https://localhost:5001/api/me -ki -H "Authorization: Bearer {valid-access-token}"
    {
     "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users/$entity",
     "businessPhones": [],
     "displayName": "Maui",
     "givenName": null,
     "jobTitle": "dev",
     "mail": null,
     "mobilePhone": null,
     "officeLocation": null,
     "preferredLanguage": null,
     "surname": null,
     "id": "cff40dac-17ea-4183-9caf-65f2ee90c562"
    }

    ℹ️ The expected response code is 200 OK if you included a valid access token as bearer token in the request.

About the code

This ASP.NET Core minimal web API has a single protected route, (/api/me), that requires callers (client applications making requests to the endpoint) present a valid access token issued by the Microsoft identity platform.

Acting as a middle-tier API, this minimal web API then uses that access token to acquire a second access token from the Microsoft identity platform, this time for Microsoft Graph, on behalf of the user.

Finally, the web API requests data from the Microsoft Graph /me endpoint and includes the response data in its response to the original caller.

This project uses the Microsoft.Identity.Web apis to interface with Microsoft Authentication Library (MSAL) for .NET. It acquires access tokens on behalf of the user, caching the resulting token in memory. Provided an access token was previously cached, the subsequent calls against /api/me will attempt to reuse the cached access token, refreshing it if nearing expiration. The MSAL is logging informational entries that state when a new access token is being acquired, cached, and re-used.

Reporting problems

Sample app not working?

If you can't get the sample working, you've checked Stack Overflow, and you've already searched the issues in this sample's repository, open an issue report the problem.

  1. Search the GitHub issues in the repository - your problem might already have been reported or have an answer.
  2. Nothing similar? Open an issue that clearly explains the problem you're having running the sample app.

All other issues

⚠️ WARNING: Any issue not limited to running this or another sample app will be closed without being addressed.

For all other requests, see Support and help options for developers | Microsoft identity platform.

Contributing

If you'd like to contribute to this sample, see CONTRIBUTING.MD.

This project has adopted the Microsoft Open Source Code of Conduct. For more information, see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.