C# Dotnet Core 2.2-Azure AD Auth工作,但角色库返回拒绝访问
我试图让角色在.NETCore2.2中工作,但其他解决方案都不起作用 在Startup.cs中,Microsoft在一个新的.Net 2.2中生成了这段代码,由于某种原因,它不起作用,但是让这个块起作用并不是主题,尽管很高兴知道为什么它不起作用。表示未指定authenticationScheme,并且未找到DefaultChallengeScheme。但这是微软创造的C# Dotnet Core 2.2-Azure AD Auth工作,但角色库返回拒绝访问,c#,azure,asp.net-core,.net-core,azure-active-directory,C#,Azure,Asp.net Core,.net Core,Azure Active Directory,我试图让角色在.NETCore2.2中工作,但其他解决方案都不起作用 在Startup.cs中,Microsoft在一个新的.Net 2.2中生成了这段代码,由于某种原因,它不起作用,但是让这个块起作用并不是主题,尽管很高兴知道为什么它不起作用。表示未指定authenticationScheme,并且未找到DefaultChallengeScheme。但这是微软创造的 services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAd(options => Configuration.Bind("AzureAd", options));
在我真正的Startup.cs中,我不得不使用下面的内容
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddAzureAd(options => Configuration.Bind("AzureAd", options))
.AddCookie();
因此,以上是我让Azure AD使用[Authorize]属性的唯一方法。问题是,当我尝试使用角色进行授权时。我试过许多建议,但都没有成功。只要我有一个[AuthorizeRoles=],我就会被重定向到Microsoft为Azure AD生成的AccountController中的AccessDenied方法,基本上拒绝访问。我正在使用我在广告中创建的角色,也在Azure广告中创建了一个组,还使用了一个名为Domain Users的角色,该角色基本上授予公司中的每个员工,是每个员工拥有的最基本的授权。如果域用户被拒绝访问,那么我不知道我在这里不理解什么
我已经关注了Microsoft文档中的角色,但是没有任何内容表明我需要添加更多的服务。添加身份验证选项。您需要在AzureAD中配置应用程序清单以接收AD角色 将清单中的groupMembershipClaims值更改为All
请注意,如果您有大量的组,则最终可能会导致响应过大,因此可能需要将所有组缩减为您实际想要流动的组。您需要在AzureAD中配置应用程序清单以接收AD角色 将清单中的groupMembershipClaims值更改为All
请注意,如果您有大量的组,则最终可能会导致响应过大,因此可能需要将所有组精简为您实际想要流动的组。请首先确认您在令牌中获得了组,在将清单中的groupMembershipClaims值更改为all后,您可以在控制器中输入以下代码:
var claims = User.Claims;
[Authorize(Policy = "CanAccessGroup")]
public IActionResult About()
{
return View();
}
在应用程序中对用户进行身份验证后,您应该获得以下组声明:
然后可以将属性与命名策略一起使用,然后在启动时定义策略以要求组声明并设置允许的组ID:
services.AddAuthorization(options =>
{
options.AddPolicy(
"CanAccessGroup",
policyBuilder => policyBuilder.RequireClaim("groups", "0c71eab2-6618-4c53-bcce-806xxxxxx"));
});
在控制器中:
var claims = User.Claims;
[Authorize(Policy = "CanAccessGroup")]
public IActionResult About()
{
return View();
}
如果组id不在用户组声明中,访问将被拒绝
表示未指定authenticationScheme,并且未找到DefaultChallengeScheme。但这是微软创造的
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAd(options => Configuration.Bind("AzureAd", options));
如果在VS2017中使用默认的工作或学校帐户模板,安装的Microsoft.AspNetCore.Authentication.AzureAD.UI软件包版本将为v2.2.0,并且生成的代码为:
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind("AzureAd", options));
请首先确认您获得了令牌中的组,将清单中的groupMembershipClaims值更改为All后,您可以在控制器中输入以下代码:
var claims = User.Claims;
[Authorize(Policy = "CanAccessGroup")]
public IActionResult About()
{
return View();
}
在应用程序中对用户进行身份验证后,您应该获得以下组声明:
然后可以将属性与命名策略一起使用,然后在启动时定义策略以要求组声明并设置允许的组ID:
services.AddAuthorization(options =>
{
options.AddPolicy(
"CanAccessGroup",
policyBuilder => policyBuilder.RequireClaim("groups", "0c71eab2-6618-4c53-bcce-806xxxxxx"));
});
在控制器中:
var claims = User.Claims;
[Authorize(Policy = "CanAccessGroup")]
public IActionResult About()
{
return View();
}
如果组id不在用户组声明中,访问将被拒绝
表示未指定authenticationScheme,并且未找到DefaultChallengeScheme。但这是微软创造的
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAd(options => Configuration.Bind("AzureAd", options));
如果在VS2017中使用默认的工作或学校帐户模板,安装的Microsoft.AspNetCore.Authentication.AzureAD.UI软件包版本将为v2.2.0,并且生成的代码为:
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind("AzureAd", options));
以下是对我有效的方法,.Net Core 2.2 Web应用程序使用角色 编辑应用程序清单以包括角色,例如
"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);
}
}
}
在企业应用程序刀片中为用户分配角色:
装饰您的控制器:
[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();
}
}
以下是对我有效的方法,.Net Core 2.2 Web应用程序使用角色 编辑应用程序清单以包括角色,例如
"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);
}
}
}
在企业应用程序刀片中为用户分配角色:
装饰您的控制器:
[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();
}
}
我把它改成了all,但我没有得到任何不同的回报。没有角色或组。您将如何精简到所需的值?我无法指定我想要的角色类型,表示无效值。但我仍然没有得到任何一个。在这一点上,我只能指向AzureAD文档,这是针对.Net核心的吗?是的,不幸的是,这是针对.Net的
,我们正在寻找与.Net Core不同的解决方案。组的流动仍应使用标志,这不是特定于.Net版本的。添加断点并查看用户是否包含角色声明。如果没有,可能是AAD配置问题。我将它改为all,但我没有得到任何不同的回复。没有角色或组。您将如何精简到所需的值?我无法指定我想要的角色类型,表示无效值。但我仍然没有得到它们。在这一点上,我只能指向AzureAD文档,这是针对.Net Core的吗?是的,不幸的是,这是针对.Net的,我们正在寻找不同于.Net Core的解决方案。组的流动仍然应该与标志一起发生,这不是针对.Net版本的。添加断点并查看用户是否包含角色声明。如果没有,可能是AAD配置问题。我想这是我迄今为止看到的最好的方法。我希望[authorized roles=]属性能够正常工作,我们能不能在团队中做到这一点?当我使用他们在模板中生成的services.AddAuthentication代码时,这就是我得到的。这是可行的,但问题是我得到了100个组。唯一的选择是使用安全组的值,这使我仍然处于100秒。我想没有别的办法可以把它删减了。但是请求/响应太大,显示错误的请求。@DanielJackson,那么您不应该使用组,使用角色,您可以在应用程序清单中定义应用程序中的角色,然后为其分配用户。一旦你做了这两件事,你得到的JWT中就会有一个名为roles的声明,其中包含用户的角色。是的,你是对的,它花了一些时间过滤掉了影响,但我现在在代码中得到了应用程序角色,并且[AuthorizeRoles=role]正在工作!谢谢你的帮助。我想这是迄今为止我见过的最好的方法。我希望[authorized roles=]属性能够正常工作,我们能不能在团队中做到这一点?当我使用他们在模板中生成的services.AddAuthentication代码时,这就是我得到的。这是可行的,但问题是我得到了100个组。唯一的选择是使用安全组的值,这使我仍然处于100秒。我想没有别的办法可以把它删减了。但是请求/响应太大,显示错误的请求。@DanielJackson,那么您不应该使用组,使用角色,您可以在应用程序清单中定义应用程序中的角色,然后为其分配用户。一旦你做了这两件事,你得到的JWT中就会有一个名为roles的声明,其中包含用户的角色。是的,你是对的,它花了一些时间过滤掉了影响,但我现在在代码中得到了应用程序角色,并且[AuthorizeRoles=role]正在工作!谢谢你的帮助。这也是我发现的。必须使用应用程序清单中定义的应用程序角色。不过最酷的是,可以在我们的常规本地广告中创建一个角色,该广告将显示在Azure广告中。该角色可以通过在应用程序清单中创建的一个角色分配给应用程序。然后,每次你向本地广告添加用户时,一旦同步到Azure广告,它就会自动获得访问权限。真酷!我在另一个Web应用程序中这样做,将它与基于策略的身份验证结合起来,它变得非常强大。例如,services.AddAuthorizationoptions=>{options.AddPolicyAnalyst,policy=>policy.requireRoledDataAnalyst;options.AddPolicyReader,policy=>policy.RequireAssertioncontext=>context.User.HasClaimClaimTypes.Role,DataAnalyst | | context.User.HasClaimClaimTypes.Role,DataReader;};我也发现了这一点。必须使用应用程序清单中定义的应用程序角色。但最酷的是,可以在我们的常规本地广告中创建角色,该广告将显示在Azure广告中。该角色可以通过在应用程序清单中创建的角色之一分配给应用程序。然后,每次将用户添加到premise AD,一旦同步到Azure AD,它将自动获得访问权限。真的很酷!我正在另一个Web应用中这样做,将它与基于策略的身份验证结合起来,它将变得非常强大。例如,services.AddAuthorizationoptions=>{options.AddPolicyAnalyst,policy=>policy.RequireRoleDataAnalyst;options.AddPolicyReader,policy=>policy.RequireAssertioncontext=>context.User.HasClaimClaimTypes.Role,DataAnalyst | | context.User.HasClaimClaimTypes.Role,DataReader;};