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