Вот что у меня работает, .Net Core 2.2 Web App с использованием ролей.
Отредактированный манифест приложения для включения ролей, например
"appRoles": [
{
"allowedMemberTypes": [
"User"
],
"description": "Admins have the power.",
"displayName": "Admin",
"id": "282fc418-cf3a-4a3a-89f8-6500c64695ff",
"isEnabled": true,
"lang": null,
"origin": "Application",
"value": "Admin"
},
{
"allowedMemberTypes": [
"User"
],
"description": "Writers have the ability to edit app data.",
"displayName": "Writer",
"id": "3aa1a322-2918-4005-8cc3-51cba010ccc0",
"isEnabled": true,
"lang": null,
"origin": "Application",
"value": "Writer"
},
{
"allowedMemberTypes": [
"User"
],
"description": "Readers have the ability to read app data.",
"displayName": "Reader",
"id": "239f93af-4cc0-4d0e-ad04-bda1f8ac2a91",
"isEnabled": true,
"lang": null,
"origin": "Application",
"value": "Reader"
}
]
Startup.cs
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddAzureAd(options => Configuration.Bind("AzureAd", options))
.AddCookie();
services.AddHttpContextAccessor();
Добавьте расширения, чтобы обойти упомянутую проблему, в своем «верхнем блоке» кода.
AzureAdAuthenticationBuilderExtensions.cs
public static class AzureAdAuthenticationBuilderExtensions
{
public static AuthenticationBuilder AddAzureAd(this AuthenticationBuilder builder)
=> builder.AddAzureAd(_ => { });
public static AuthenticationBuilder AddAzureAd(this AuthenticationBuilder builder, Action<AzureAdOptions> configureOptions)
{
builder.Services.Configure(configureOptions);
builder.Services.AddSingleton<IConfigureOptions<OpenIdConnectOptions>, ConfigureAzureOptions>();
builder.AddOpenIdConnect();
return builder;
}
private class ConfigureAzureOptions : IConfigureNamedOptions<OpenIdConnectOptions>
{
private readonly AzureAdOptions _azureOptions;
public ConfigureAzureOptions(IOptions<AzureAdOptions> azureOptions)
{
_azureOptions = azureOptions.Value;
}
public void Configure(string name, OpenIdConnectOptions options)
{
options.ResponseType = "token id_token";
options.Resource = _azureOptions.TargetApiAppId;
options.SaveTokens = true;
options.ClientId = _azureOptions.ClientId;
options.Authority = $"{_azureOptions.Instance}{_azureOptions.TenantId}";
options.UseTokenLifetime = true;
options.CallbackPath = _azureOptions.CallbackPath;
options.RequireHttpsMetadata = false;
}
public void Configure(OpenIdConnectOptions options)
{
Configure(Options.DefaultName, options);
}
}
}
AzureADOptions.cs
public class AzureAdOptions
{
public string ClientId { get; set; }
public string ClientSecret { get; set; }
public string Instance { get; set; }
public string Domain { get; set; }
public string TenantId { get; set; }
public string CallbackPath { get; set; }
//manually added
public string TargetApiAppId { get; set; }
}
Назначьте роль пользователю в блейде корпоративных приложений:
Украсьте свой контроллер:
[Authorize(Roles = "Writer")]
AccountController.cs
public class AccountController : Controller
{
[HttpGet]
public IActionResult SignIn()
{
var redirectUrl = Url.Action(nameof(HomeController.Index), "Home");
return Challenge(
new AuthenticationProperties { RedirectUri = redirectUrl },
OpenIdConnectDefaults.AuthenticationScheme);
}
[HttpGet]
public IActionResult SignOut()
{
var callbackUrl = Url.Action(nameof(SignedOut), "Account", values: null, protocol: Request.Scheme);
return SignOut(
new AuthenticationProperties { RedirectUri = callbackUrl },
CookieAuthenticationDefaults.AuthenticationScheme,
OpenIdConnectDefaults.AuthenticationScheme);
}
[HttpGet]
public IActionResult SignedOut()
{
if (User.Identity.IsAuthenticated)
{
// Redirect to home page if the user is authenticated.
return RedirectToAction(nameof(HomeController.Index), "Home");
}
return View();
}
[HttpGet]
public IActionResult AccessDenied()
{
return View();
}
}