Quickstart: Protect an ASP.NET Core web API with the Microsoft identity platform

This quickstart uses an ASP.NET Core web API code sample to demonstrate how to restrict resource access to authorized accounts. The sample uses ASP.NET Core Identity that interacts with Microsoft Authentication Library (MSAL) to handle authentication.

Prerequisites

Register the application and record identifiers

Tip

Steps in this article might vary slightly based on the portal you start from.

To complete registration, provide the application a name and specify the supported account types. Once registered, the application Overview page displays the identifiers needed in the application source code.

  1. Sign in to the Microsoft Entra admin center as at least an Application Developer.

  2. If you have access to multiple tenants, use the Settings icon in the top menu to switch to the tenant in which you want to register the application from the Directories + subscriptions menu.

  3. Browse to Identity > Applications > App registrations.

  4. Select New registration.

  5. Enter a Name for the application, such as NewWebAPI1.

  6. For Supported account types, select Accounts in this organizational directory only. For information on different account types, select Help me choose option.

  7. Select Register.

    Screenshot that shows how to enter a name and select the account type.

  8. The application's Overview pane is displayed when registration is complete. Record the Directory (tenant) ID and the Application (client) ID to be used in your application source code.

    Screenshot that shows the identifier values on the overview page.

Note

The Supported account types can be changed by referring to Modify the accounts supported by an application.

Expose an API

Once the API is registered, you can configure its permission by defining the scopes that the API exposes to client applications. Client applications request permission to perform operations by passing an access token along with its requests to the protected web API. The web API then performs the requested operation only if the access token it receives contains the required scopes.

  1. Under Manage, select Expose an API > Add a scope. Accept the proposed Application ID URI (api://{clientId}) by selecting Save and continue. The {clientId} is the value recorded from the Overview page. Then enter the following information:

    1. For Scope name, enter Forecast.Read.
    2. For Who can consent, ensure that the Admins and users option is selected.
    3. In the Admin consent display name box, enter Read forecast data.
    4. In the Admin consent description box, enter Allows the application to read weather forecast data.
    5. In the User consent display name box, enter Read forecast data.
    6. In the User consent description box, enter Allows the application to read weather forecast data.
    7. Ensure that the State is set to Enabled.
  2. Select Add scope. If the scope has been entered correctly, it's listed in the Expose an API pane.

    Screenshot that shows the field values when adding the scope to an API.

Clone or download the sample application

To obtain the sample application, you can either clone it from GitHub or download it as a .zip file.

  • To clone the sample, open a command prompt and navigate to where you wish to create the project, and enter the following command:

    git clone https://github.com/Azure-Samples/ms-identity-docs-code-dotnet.git
    
  • Download the .zip file. Extract it to a file path where the length of the name is fewer than 260 characters.

Configure the ASP.NET Core sample application

  1. In your IDE, open the project folder, ms-identity-docs-code-dotnet/web-api, containing the sample.

  2. Open appsettings.json file, which contains the following code snippet:

    {
      "AzureAd": {
        "Instance": "https://login.microsoftonline.com/",
        "TenantId": "Enter the tenant ID obtained from the Microsoft Entra admin center",
        "ClientId": "Enter the client ID obtained from the Microsoft Entra admin center",
        "Scopes": "Forecast.Read"
      },
      "Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft.AspNetCore": "Warning"
        }
      },
      "AllowedHosts": "*"
    }
    

    Find the following key:

    • ClientId - The identifier of the application, also referred to as the client. Replace the value text in quotes with Application (client) ID that was recorded earlier from the Overview page of the registered application.
    • TenantId - The identifier of the tenant where the application is registered. Replace the value text in quotes with Directory (tenant) ID value that was recorded earlier from the Overview page of the registered application.

Run the sample application

  1. Execute the following command to start the app:

    dotnet run
    
  2. An output like the following sample appears:

    ...
    info: Microsoft.Hosting.Lifetime[14]
          Now listening on: https://localhost:{port}
    ...
    

    Record the port number in the https://localhost:{port} URL.

  3. To verify the endpoint is protected, use the following cURL command in Bash to send an unauthenticated HTTP GET request in Bash:

    curl -X GET https://localhost:5001/weatherforecast -ki
    

    The expected response is 401 Unauthorized with output similar to:

    user@host:~$ curl -X GET https://localhost:5001/weatherforecast -ki
    HTTP/2 401
    date: Fri, 23 Sep 2023 23:34:24 GMT
    server: Kestrel
    www-authenticate: Bearer
    content-length: 0