I am struggling to get user information from Azure AD, with Microsof Graph with a .NET Core API. I tried a couple tutorials but I got stuck on several issues.
Microsoft Graph Connect Sample for ASP.NET Core 3.1 https://learn.microsoft.com/en-us/samples/microsoftgraph/aspnetcore-connect-sample/microsoft-graph-connect-sample-for-aspnet-core-31/)
This tutorial look promising, but it turns out it requires a multi tenant Azure Application - but mine is Single Tenant.
Call MS Graph APIs from ASP.NET Core 3.1 (https://github.com/cmatskas/aspnetcorewithgraph/blob/master/WebApplication1/Startup.cs)
This tutorial look interesting but it uses two NuGet packages in preview mode. And when I try the code (see my startup.cs) it throws issues saying
"The MetadataAddress or Authority must use HTTPS unless disabled for development by setting RequireHttpsMetadata=false."
I tried set it to false in my addJwTBearer option, but the issue remains.
Any chance you guys know of a good tutorial for my case, or what is wrong with my startup file?
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
// APISettings
services.Configure<APISettings>(Configuration.GetSection("APISettings"));
services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
// Add our Config object so it can be injected
//services.Configure<MyConfig>(Configuration.GetSection("MyConfig"));
AppConstants.AppUserRoles = new AppUserRoles();
AppConstants.AppUserRoles.AdminDatabaseID = Configuration.GetSection("AppSettings").GetSection("AppUserRoles").GetValue<int>("AdministratorDatabaseID");
AppConstants.AppUserRoles.UserDatabaseID = Configuration.GetSection("AppSettings").GetSection("AppUserRoles").GetValue<int>("UserDatabaseID");
AppConstants.AppUserRoles.ManagerDatabaseID = Configuration.GetSection("AppSettings").GetSection("AppUserRoles").GetValue<int>("ManagerDatabaseID");
// Repositories
services.AddTransient<IUserRepository, UserRepository>();
services.AddTransient<ITimeLogRepository, TimeLogRepository>();
services.AddTransient<IReportRepository, ReportRepository>();
services.AddTransient<ICalendarRepository, CalendarRepository>();
// Models
services.AddTransient<CreateTimeLogResponse>();
// Services
services.AddTransient<IHttpContextAccessor, HttpContextAccessor>();
services.AddTransient<IDatabase, Database>();
services.AddTransient<ISessionService, SessionService>();
services.AddTransient<IIdentityClaimService, IdentityClaimService>();
services.AddTransient<IUserService, UserService>();
services.AddTransient<TimeLogService>();
services.AddTransient<ReportsService>();
services.AddTransient<ICalendarService, CalendarService>();
// AutoMapper
services.AddAutoMapper(typeof(Startup));
// Were only using API.
services
.AddControllers().AddJsonOptions(options =>
{
options.JsonSerializerOptions.Converters.Add(new DateTimeConverter());
options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
});
// Azure AD Authentication
services
.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
var authSettings = Configuration.GetSection("AzureAd").Get<AzureAdOptions>();
options.Audience = authSettings.ClientId;
options.Authority = authSettings.Authority;
options.RequireHttpsMetadata = false;
});
// MS Graph.
services.AddSignIn(Configuration);
services.AddWebAppCallsProtectedWebApi(Configuration, new string[] { "user.read" })
.AddInMemoryTokenCaches(); // Or .AddDistributedTokenCaches(); depending on which token cache provider from Microsoft.Identity.Web you would like to use.
services.AddGraphService(Configuration);
// In production, the React files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/build";
});
services.AddDistributedMemoryCache();
services.AddSession(options =>
{
// Set a short timeout for easy testing.
options.IdleTimeout = TimeSpan.FromMinutes(1);
options.Cookie.HttpOnly = true;
// Make the session cookie essential
options.Cookie.IsEssential = true;
});
}