Hello
The error message you received suggests that Microsoft.Identity.Web was not able to determine the cloud instance for your app. This can happen if the AzureAd section in your configuration is missing the Instance key, which is used to specify the Azure AD authority.
To use Microsoft.Identity.Web with Windows Authentication in an on-premise MVC web app, you can follow these steps:
Add the Microsoft.Identity.Web NuGet package to your project.
Update the authentication middleware in your Startup.cs to use AddMicrosoftIdentityWebApi instead of AddNegotiate:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
**.AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAd"));**
Note that we are using JwtBearerDefaults.AuthenticationScheme instead of NegotiateDefaults.AuthenticationScheme, since we will be using a JWT bearer token to authenticate requests to Microsoft Graph.
- Configure your app to use Windows Authentication by adding the following code to your
ConfigureServices method:
services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
**.AddNegotiate();**
services.AddAuthorization();
services.AddControllers();
- In your
Configure method, add the following middleware to enable Windows Authentication:
app.UseAuthentication();
app.UseAuthorization();
- Update your app's configuration to include the necessary settings for Microsoft.Identity.WebApi, including the
Instance key:
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "<your-tenant-name>.onmicrosoft.com",
"TenantId": "<your-tenant-id>",
"ClientId": "<your-client-id>",
"CallbackPath": "/signin-oidc"
},
"DownstreamApi": {
"BaseUrl": "https://graph.microsoft.com/v1.0",
"Scopes": "User.Read.All"
}
Note that the Instance value should be set to https://login.microsoftonline.com/ followed by your Azure AD tenant ID or domain name.
- Finally, you can use the
AddMicrosoftIdentityWebApi extension method to configure token acquisition and Microsoft Graph access for your app. Here's an example:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
**.AddMicrosoftIdentityWebApi(Configuration.GetSection("AzureAd"));**
services.Configure<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme, options =>
{
**options.TokenValidationParameters.ValidAudiences = new[] { "https://graph.microsoft.com" };**
**options.TokenValidationParameters.NameClaimType = "name";**
});
services.AddHttpClient();
services.AddTransient<GraphServiceClient>(sp =>
{
**var httpClient = sp.GetRequiredService<HttpClient>();**
**var graphOptions = Configuration.GetSection("DownstreamApi").Get<DownstreamApiOptions>();**
**var tokenAcquisitionOptions = new TokenAcquisitionOptions();**
**var tokenAcquisition = sp.GetRequiredService<ITokenAcquisition>();**
**var accessToken = tokenAcquisition.GetAccessTokenForUserAsync(graphOptions.Scopes.Split(' '), user: null).Result;**
**httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);**
**return new GraphServiceClient(httpClient);**
});
This code registers an instance of the Microsoft Graph SDK's GraphServiceClient as a transient service, using an HttpClient instance configured with an access token obtained using the ITokenAcquisition service. Note that the TokenValidationParameters are set to specify the audience and name claim type for the JWT bearer token.
I hope this helps !
If it does kindly mark the answer as Accepted and upvote or send us additional feedback !
Regards