I published an ASP.NET web app to Azure, but I’m not getting the sign-in screen.
I’m able to call the API and retrieve data when I set the Restrict access option to Allow unauthenticated access. I have followed this guide: https://learn.microsoft.com/en-us/azure/app-service/scenario-secure-app-authentication-app-service?tabs=workforce-configuration#dnl-note which states "You should be directed to a secured sign-in page, verifying that unauthenticated users aren’t allowed access to the site." In my case this sign-in page is never shown, instead I just see a blank page with the text "You do not have permission to view this directory or page."
Am I missing or forgetting something?
Minimal reproducible example
Create Web app
- Open Visual Studio and then select Create a new project.
- In Create a new project, find, and select ASP.NET Core Web API, then select Next.
- In Configure your new project, name the application WebAppApi, and then select Next.
- Additional information: Framework: .NET 8.0, Authentication type: None, Configure for HTTPS, Do not use top-level statements, Use controllers
- Select Create.
- Run the application
- The browser should now display some data retrieved through the web app.
Create Azure Web App
- Go to Azure portal
- Go to Web Services
- Select Create Web App
- Name the Web App "WebAppApi".
- Use the settings: runtime stack: .NET 8, Pricing plan: Free F1
- Enable basic authentication
- Use default settings otherwise and create.
- After deployment, go to Download publish profile
Publish web app
- Right click the project -> Publish
- Import the downloaded publish profile
- Press publish
- Now you can go to the Default domain link in the overview page of the web app and add "/weatherforecast", you should see the same data as running it in Visual Studio
This works great, except that anyone can access this API. I would like to use Microsoft Authentication to restrict access to just the users within my organization.
Add app authentication to your web app running on Azure App Service
- In the Azure Web App go to Settings – Authentication
- Add identity provider
- Select Microsoft
- Select Workforce configuration
- Select Create new app registration
- Name: WebAppApi
- Account type: Current tenant
- Allow requests only from this application itself
- Allow requests from any identity
- Allow requests only from the issuer tenant
- Require authentication
- HTTP 401 Unauthorized: recommended for APIs
- Check Token store box
- Select Add
Verify access
- Go to the Default domain link in the overview page of the web app and add "/weatherforecast" (same as before)
- You will see a message "You do not have permission to view this directory or page." instead of a sign-in page as the guide mentioned
Update
I’m able to get the sign in page by adding the following code to a desktop client application calling the API:
IPublicClientApplication publicClientApplication = PublicClientApplicationBuilder.Create(<client-app-registration-id>)
.WithAuthority(AzureCloudInstance.AzurePublic, <tenant-id>)
.WithRedirectUri("http://localhost")
.Build();
string[] scopes = [<registered-scope>];
AuthenticationResult result = await publicClientApplication.AcquireTokenInteractive(scopes).ExecuteAsync();
string accessToken = result.AccessToken;
using HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
HttpResponseMessage response = await client.GetAsync(<api-address>);
I created a new app registration for a desktop client which has a permission for a scope defined by the WebAppApi registration.
I checked the token I received and the aud, iss and appid seem correct. Still the HttpResponseMessage is StatusCode: 401, ReasonPhrase: ‘Unauthorized’.
2
Answers
I got the authentication working. Thanks to Shiraz Bhaiji's answer I started looking into the token sent by the client. I started implementing my own AuthenticationHandler on the server side to see what was going on. I think one of the issues was that the authentication issuer wasn't matching: the server was expecting login.microsoftonline.com, but the client was sending sts.windows.net.
After some googling I found a fix by changing requestedAccessTokenVersion from "null" to "2" in the App Registration manifest on Azure.
You do not get a sign in page when you have an API project.
The API expects that authentication information is sent in the HTTP header when you make the call.