我正试图在测试应用程序上使用[Authorize(Roles="test")]和/或调用User.IsInRole("test"。完成此操作后,我可以在(ClaimsPrincipal.Current.Identity as ClaimsIdentity).FindAll("groups")中看到测试组的SID,但Authorize属性和对IsInRole的调用不起作用。还有什么必要让它发挥作用吗?
Azure AD不发送Role声明中的组,也不发送组的名称(在多租户系统中,这没有多大意义:contoso中的"admin"可能与fabrikam中的"admin"具有完全不同的语义)。Azure AD有一个新的结构,它表示实际的角色,而不是组。如果要根据角色的名称检查访问权限,请参阅https://github.com/Azure-Samples/active-directory-dotnet-webapp-roleclaims/blob/master/WebApp-RoleClaims-DotNet用于使用应用程序角色的示例。如果要检查组的授权,则需要将组声明类型分配为RoleClaimType(在https://github.com/Azure-Samples/active-directory-dotnet-webapp-roleclaims/blob/master/WebApp-RoleClaims-DotNet/App_Start/Startup.Auth.cs您可以看到它是如何为应用程序角色完成的),以便ASP.NET在Authorize和IsInRole发挥作用时知道它是要验证的声明。此外,考虑到你没有;t获取组的名称,您需要根据组的objectId执行检查。如果你想使用组并对照组名进行检查,这会变得很复杂。您需要调用图形API来将组的ObjectId转换为其名称,并相应地增加传入声明集合。
在ASP.NET 5和MVC 6中,您只需要进行正确的配置。以下是对我来说很有魅力的代码:
public void ConfigureApplication(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
...
app.UseIISPlatformHandler();
app.UseStaticFiles();
app.UseCookieAuthentication(options =>
{
options.AutomaticAuthenticate = true;
});
app.UseOpenIdConnectAuthentication(options =>
{
options.AutomaticChallenge = true;
options.ClientId = Configuration.Get<string>("Authentication:AzureAd:ClientId");
options.Authority = Configuration.Get<string>("Authentication:AzureAd:AADInstance") + "Common";
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false,
RoleClaimType = "roles"
};
options.Events = new OpenIdConnectEvents
{
OnAuthenticationValidated = (context) => Task.FromResult(0),
OnAuthenticationFailed = (context) =>
{
context.Response.Redirect("/Home/Error");
context.HandleResponse(); // Suppress the exception
return Task.FromResult(0);
},
OnRemoteError = (context) => Task.FromResult(0)
};
});
app.UseMvc(routes =>
{
routes.MapRoute(name: "default", template: "{controller=Dashboard}/{action=Index}/{id?}");
});
DatabaseInitializer.InitializaDatabaseAsync(app.ApplicationServices).Wait();
}