MicrosoftDocs / azure-docs

Open source documentation of Microsoft Azure
https://docs.microsoft.com/azure
Creative Commons Attribution 4.0 International
10.3k stars 21.48k forks source link

Quickstart: Protect an ASP.NET Core web API with the Microsoft identity platform seems incomplete #87179

Closed kmb385 closed 2 years ago

kmb385 commented 2 years ago

This quickstart provides a quick synopsis of how to protect a web api with Microsoft Identity platform, however it lacks any description of how to securely call the api once the security scheme is established. Without these instructions the learner will always encounter 401 errors when sending requests to the API or they will need to do additional research to learn how to obtain an access token to pass with the request.

After following the instructions in the quickstart, I needed to complete the following steps to make an authorized call to the protected web api that was provided as an example.

Additional Azure Configuration: Add Redirect URI

  1. Go to App registrations, click owned apps and then select the application.
  2. Underneath the manage section, select Authentication.
  3. Under Platform configurations, click the option to Add a platform
  4. Provide the redirect URI of the application. In my case postman's redirect support: https://oauth.pstmn.io/v1/callback

Additional Azure Configuration: Add Redirect URI

  1. Go to App registrations, click owned apps and then select the application.
  2. Underneath the manage section, select Certificates and Secrets.
  3. Click the button to add a New client secret
  4. Provide the description for the client
  5. Copy the Value (Secret) and Secret ID (Client Id) for use in Postman configuration. These terms are a little off from the oAuth2.0 spec.

Postman Request Configuration

After these configurations are in place within Azure,the learner will have everything they require to successfully make a call to the API via a tool like Postman. Here are the instructions for configuring a postman request.

  1. Create a new request to the api endpoint for my local machine: https://localhost:44393/WeatherForecast
  2. Click the Authorization Tab and provide the following values:
  3. Click Get New Access Token then complete the Microsoft Authentication Flow.
  4. Click use token
  5. Send the request to the API endpoint.

So there is quite a bit of extra work to make a successful request to the protected web api that is not covered by the quickstart and can be a little confusing when completing it. At a minimum I would recommend linking to any pre-existing documention that contains similar instructions. Otherwise, its going to leave the learner unclear as to whether they have properly configured the application and the service, which doesn't create a nice onboarding or first experience with an otherwise awesome product.


Document Details

Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

YutongTie-MSFT commented 2 years ago

Thanks for the feedback! I have assigned the issue to the content author to investigate further and update the document as appropriate.

kmb385 commented 2 years ago

Awesome! Glad to provide any additional feedback on the item. Thanks for looking into it.

mmacy commented 2 years ago

Great issue writeup, @kmb385. We're currently building out new multi-article tutorial series for this and other application types/scenarios, and calling the protected API will absolutely be included in our "Protect an API" tutorial series.

@Dickson-Mwendia I'll leave this open for you review and perhaps close for now, but @kmb385 was kind enough to include a full step-by-step for testing with Postman that we can likely leverage in our upcoming tutorials. That was above-and-beyond the call of duty but is very much appreciated, @kmb385 - thanks again! 🥇

kmb385 commented 2 years ago

@mmacy My pleasure! Thank you for the excellent learning materials! I'll actually become part of the team at Microsoft on February 14th and these quickstarts have been so helpful as part of my ramp up!

mmacy commented 2 years ago

@kmb385 Great! One quick fix to your issue description:

image

@Dickson-Mwendia We'll need to balance the convenience/ease of adding a redirect URI to the same app registration as the web API vs. creating a new app registration for Postman (to act as the client app). Best practice is to use separate app registrations for client and resource, so having people use the same app reg for both while following a tutorial risks sending the wrong message.

Having said that, what we could do is write _Test your $APP_TYPE's [authentication | authorization] with Postman_ how-to articles, and the "Register Postman as a client application" section could be an INCLUDE that we use for the tutorial series.

kmb385 commented 2 years ago

@mmacy Thanks for pointing out the single registration situation. I overlooked that and hadn't recognized that both Apps and their clients are registered underneath the same mechanism in Azure Active Directory. This morning I walked through the process and have what I believe are some pretty decent updated instructions. If you would like, I can share them, but thought I would ask first so I didn't clutter up your team's workflow.

kmb385 commented 2 years ago

I'll take it the heart means share! Here they are...

Here are updated instructions which attempt to walk through registration of the client application.

Registering a Client Application to Call the Web API

After registering, exposing and protecting the ASP.NET Core web API an authorized client of the API can now send it requests. A client might be any other piece of software, such as a Single Page Application or desktop application that needs to call the API. Since access to the web API is restricted by the established scope, it will require clients that call it to be registered with the Microsoft Identity platform via a separate app registration and granted the scope.

Postman, is a popular application that developers use to test API calls, which can be used as a client for testing authorized calls to the API protected by the Microsoft Identity platform.

Step 1: Register the Postman Client

  1. Sign in to the Azure portal.
  2. If you have access to multiple tenants, use the Directories + subscriptions filter in the top menu to switch to the tenant in which you want to register the application.
  3. Search for and select Azure Active Directory.
  4. Under Manage, select App registrations > New registration.
  5. For Name, enter a name for the client application. For example, enter WebApi-Quickstart-Client.
  6. For Redirect URI, select Web and then provide the URL: https://oauth.pstmn.io/v1/callback a. Postman uses this URI to extract the authorization code or token. For scenarios outside of testing, you’ll want to establish your own Redirect URI and this should not be used for live production code.
  7. Select Register.

Step 2: Grant the New Client Application the Required Scopes

  1. From Azure Active Directory, click App registrations underneath the Manage section, then click the new client application.
  2. Underneath the manage section, select API Permissions, then click the Add a permission button.
  3. In the new pane that appears, click the APIs my organization uses tab. In this list, select the API you previously registered, in this case AspNetCoreWebApi-Quickstart.
  4. Under Select permissions, check the access_as_user scope required to access the API and then click Add permissions.
  5. The new permissions will be requested for the client and listed in the permissions list. After consent is granted is granted by a global administrator of your directory the permission will be assigned to the client application. If you are a global tenant administrator, you can grant the client application the permission by clicking on the Grant admin consent for {Tenant Name}.

Step 3: Create Credentials for the New Client Application

After the client has been registered and assigned the appropriate permissions, you’ll need to create credentials the client can use to obtain a token to access the web API.

  1. From Azure Active Directory, go to App registrations, click owned apps and then click the new client application.
  2. Underneath the manage section, select Certificates and Secrets.
  3. Click the button to add a New client secret
  4. Provide the description for the client and then click Add.
  5. Copy the Value, which is the client secret and store it some place safe for later use.

Step 4: Configure an authorized request to the web API in Postman

After these configurations are in place within Azure Active Directory, you’ll have everything required to successfully make an authorized request to the API via Postman.

  1. To begin, create a new request in Postman by selecting File > New, then Http Request.
  2. For the request URL, enter the URL of the endpoint exposed by the web API, https://localhost:44393/WeatherForecast
  3. Next, click the Authorization tab to configure Postman to obtain a token from the Microsoft Identity platform that will grant access to the API.
  4. From the type dropdown, select OAuth 2.0. This will display a form where you’ll provide details about your Azure Active Directory configuration that Postman will use to obtain the token.
  5. For the Token Name, provide any name for the token.
  6. For the Grant Type, select Authorization Code.
  7. Check the Authorize using browser checkbox, which will set the Callback URL to the Redirect URI registered with Azure Active Directory.
  8. Set the Auth URL to: https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/authorize a. To obtain this value from Azure Active Directory, navigate to your registered application and click the Endpoints button on the overview section.
  9. Set the Access Token URL to: https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token a. To obtain this value from Azure Active Directory, navigate to your registered application and click the Endpoints button on the overview section.
  10. Set the Client ID to the value of the Application (client) ID found on the overview section of the registered application within Azure Active Directory.
  11. Set the Client Secret to the value obtained and stored away in step 3.
  12. Set the scope to the value Azure Active Directory assigned when you exposed the Web API (example: api://{Application ID}/access_as_user) a. To obtain this value from Azure Active Directory, navigate to your registered application and select API permissions under the manage section. b. Then click on the access_as_user permission to obtain the value displayed in the textbox from the pane that appears.
  13. In Postman, click the Get New Access Token Button a. This will launch a browser window where you’ll authenticate with your user credentials. b. Be sure to allow pop ups from the Postman application in the browser.
  14. After authenticating, click the Use Token button in Postman to provide the access token in the request.
  15. Then click the Send button in Postman to send the request to the protected web API endpoint. After sending the request, you should receive a response from the API that has a 200 Status Code
mmacy commented 2 years ago

@kmb385 Wow! That's awesome. And, yes, the heart meant share - here's what I had written but failed to hit the Comment button:

@kmb385 Absolutely, please do share, and don't worry about cluttering up our workflow. We appreciate all constructive criticism and feedback, and especially appreciate contributions like yours. There are several ways to contribute to docs, including contributing directly to the MicrosoftDocs/azure-docs repo, but it's typically lower-friction (and thus quicker) to hack out ideas in an issue first and then migrate it to a full-on docs article(s).

mmacy commented 2 years ago

@kmb385 We do have similar prior art here that we might leverage and/or expand to support custom web APIs and surface it in the identity platform docs:

I've added this work to our backlog (Microsoft-internal):

ID Title
1765243  [ISSUE][87179] NEW article: Test a protected web API with Postman

I've also propped your steps from https://github.com/MicrosoftDocs/azure-docs/issues/87179#issuecomment-1029257381 to this Gist: How to test a protected web API with Postman

I'll now close this issue as we're tracking internally and will pull it off the backlog as resources permit. #please-close

Thanks again for the issue and the procedure! 🥇