I have an ASP.NET Core Web Api 6 project generated by VS 2022, with MicrosoftIdentity authentication. The required identifiers for logging in to AzureAd were filled in, AzureAD:ClientSecret was also saved in secrets.json.
It looks like this:
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.Resource;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi()
.AddMicrosoftGraph(builder.Configuration.GetSection("MicrosoftGraph"))
.AddInMemoryTokenCaches();
builder.Services.AddAuthorization();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
var scopeRequiredByApi = app.Configuration["AzureAd:Scopes"] ?? "";
{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "xxxxxxxxx",
"TenantId": "xxxxxxxxxxxxxxxxxxxxxxxxxxx,
"ClientId": "xxxxxxxxxxxxxxxxxxxxxxxxxxx",
"CallbackPath": "/signin-oidc",
"Scopes": "access_as_user",
"ClientSecret": "Client secret from app-registration. Check user secrets/azure portal.",
"ClientCertificates": []
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"MicrosoftGraph": {
"BaseUrl": "https://graph.microsoft.com/v1.0",
"Scopes": "user.read"
}
}
Identifiers have been replaced with the text xxxxx.
I need to call MicrosoftGraph services, for example api for 'Get User'.
The Microsoft documentation lists this code:
GraphServiceClient graphClient = new GraphServiceClient( authProvider );
var user = await graphClient.Users["{user-id}"]
.Request()
.GetAsync();
The above configuration of the ASP.NET Web Api project contains all the identifiers required for authorization.
How to create an authProvider variable using the configured identifiers in the above context?
Well thank you.
CodePudding user response:
This line
.AddMicrosoftGraph(builder.Configuration.GetSection("MicrosoftGraph"))
adds the support for GraphServiceClient
via dependency injection
In your controller: add GraphServiceClient
parameter into the constructor and dependency injection will resolve the instance of GraphServiceClient
with configured authProvider
.
public class YourController
{
private GraphServiceClient _graphServiceClient;
public YourController(GraphServiceClient graphServiceClient)
{
_graphServiceClient = graphServiceClient;
}
...
}
CodePudding user response:
Thanks. I use "minimal api", so this should work too:
app.MapGet("/getuser", (Microsoft.Graph.GraphServiceClient client) =>
{
return (new MsTeamsMe().Run(client));
});
Unfortunately, the GraphServiceClient client configured in this way does not work properly. So it seems to me that it is safer - due to the significant complexity of authorization - to generate a functional GraphServiceClient instance manually:
GraphServiceClient CreateClient()
{
var scopes = new string[] { "https://graph.microsoft.com/.default" };
var tenantId = TeamsConstants.TenantId;
// Configure the MSAL client as a confidential client
var confidentialClient = ConfidentialClientApplicationBuilder
.Create(TeamsConstants.ClientId)
.WithAuthority($"https://login.microsoftonline.com/{tenantId}/v2.0")
.WithClientSecret(TeamsConstants.ClientSecretValue)
.Build();
// Build the Microsoft Graph client. As the authentication provider, set an async lambda
// which uses the MSAL client to obtain an app-only access token to Microsoft Graph,
// and inserts this access token in the Authorization header of each API request.
return new GraphServiceClient(new DelegateAuthenticationProvider(async (requestMessage) =>
{
// Retrieve an access token for Microsoft Graph (gets a fresh token if needed).
var authResult = await confidentialClient
.AcquireTokenForClient(scopes)
.ExecuteAsync();
// Add the access token in the Authorization header of the API request.
requestMessage.Headers.Authorization =
new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
})
);
}