I created a Azure .NET 7 sample Web API and wanted to publish it to my Azure App service - configured, then selected Publish button in Visual Studio and after a while I've got success information in Output window. After that, browser is opened with my site's address but it returns not found 404 error
I have added Microsoft Identity platform (previously Azure AD) - maybe that somehow affects this, but I am using same Azure AD for my other Azure API without issues.
When I run locally this API is started and page is opened in browser successfully.
content of appsettings.json
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "....onmicrosoft.com",
"TenantId": "...",
"ClientId": "...",
"CallbackPath": "/signin-oidc",
"Scopes": "access_as_user"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"MicrosoftGraph": {
"BaseUrl": "https://graph.microsoft.com/v1.0",
"Scopes": "user.read"
}
}
I followed steps in Visual Studio Web API creation wizard In publish window connection validates successfully
Also checked this quickstart guide - didn't notice anything that I might have done wrong, but it's for .NET 6, not .NET 7, so maybe .NET 7 need to do something differently
It should redirect to https://login.microsoftonline.com/... for authorization, but it just returns not found
From this stackoverflow post found out that I need to manually create a web.config for my API, got this far with creating it, but seems like still missing something
<?xml version="1.0" encoding="utf-8"?> <configuration> <location path="." inheritInChildApplications="false"> <system.webServer> <handlers> <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" /> </handlers> <aspNetCore processPath="dotnet" arguments=".\MyWebApp.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="InProcess" /> </system.webServer> <system.web> <httpRuntime targetFramework="net6.0" /> </system.web> </location> </configuration>
Update
Turns out it is not working also locally - when trying out endpoint through swagger it returns 401 www-authenticate bearer
Update2
When I created Web API I selected to use Microsoft Identity platform
and this code was generated. Do I need to configure AddJwtBearer here?
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd")) .EnableTokenAcquisitionToCallDownstreamApi() .AddMicrosoftGraph(builder.Configuration.GetSection("MicrosoftGraph")) .AddInMemoryTokenCaches();
When we create the Web API project, and run it locally, it will redirect to he Swagger UI to list all the APIs and help test the api, but it doesn't mean the Swagger page is the default website, it will only appear when in the development environment, after publishing to Azure web app, the API home page will be xx.azurewebsite.net
but there's no API or View bind to this route, so a 404 error indicating that there's no API in the application which the routing is xx.azurewebsite.net
. And normally, the API routing should look like xx.azurewebsite.net/api/controller/xx
If you want your web API to be protected by Azure AD, you can take a look at this document. To summarize here, you need to add Cors policy and add Azure ad authentication into Program.cs
.
using Microsoft.Identity.Web;
builder.Services.AddCors(options =>
{
options.AddPolicy(name: "mypolicy",
policy =>
{
policy.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod();
});
});
builder.Services.AddMicrosoftIdentityWebApiAuthentication(builder.Configuration);
...
app.UseCors("mypolicy");
app.UseAuthentication();
app.UseAuthorization();
Then here it used some configuration, you need to add configuration in appsettings.json
. The value of the properties you can follow the document to create Azure AD resource and get them.
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"ClientId": "azure_ad_app_id",
"ClientSecret": "client_secret",
"Domain": "tenant_id",
"TenantId": "tenant_id"
//I used the same azure application which exposed api and add api permission,so I can comment this line
//"Audience": "api://azure_ad_app_id_which_exposed_api"
},
Finally, in the Controller, add [Authorize]
before the controller. Then the api now is protected by Azure AD, you have to have a correct access token to visit it.
Assume you are exposing a delegate API permission. Then the api permission you assigned to your Azure AD application should look like api://azure_ad_app_id_exposed_api/permission_name_you_defined
. Then you can use following link to use auth code flow to generate access token.
https://login.microsoftonline.com/tenant_id/oauth2/v2.0/authorize?
client_id=azure_ad_app_id
&response_type=code
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&response_mode=query
&scope=profile email openid offline_access
&state=12345
Visiting the URL above will ask you to sign in with your microsoft account, after sign in successfully, you will see URL in the browser like copy the value of the code, you need to use it next.
http://localhost/myapp/?
code=0.ASxxx
&state=12345&session_state=c71be61a-c4cc-4624-9fa4-fe6c4b2d6b88
Then use the request like below to generate the access token:
Post: https://login.microsoftonline.com/tenant_id/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded
client_id=azure_ad_app_id
&scope=api://azure_ad_app_id_exposed_api/api_name
&code=O.xxxx
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&grant_type=authorization_code
&client_secret=client_secret