我在 ASP网络论坛. 当我尝试为我的net core 3.1应用程序实现时,出现错误
I've seen basically the same question answered for net core 2.2 on ASP Net Forum. When I tried to implement for my net core 3.1 application, I'm getting an error
System.InvalidCastException: Unable to cast object of type 'System.Security.Claims.ClaimsIdentity' to type 'System.Security.Principal.WindowsIdentity'在RoleAuthHandler.cs尝试将Identity强制转换为WindowsIdentity时发生错误.
The error happens on the RoleAuthHandler.cs trying to cast Identity to WindowsIdentity.
我想知道核心2.2和3.1之间是否有更改可以解释这一点,或者我做错了什么.任何帮助都会很棒.
I'm wondering if there has been change between core 2.2 and 3.1 that explains this or I'm doing something wrong. Any help would be great.
Startup.cs包含
Startup.cs contains
public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddSingleton<IAuthorizationHandler, RoleAuthHandler>(); services.AddAuthorization(options => options.AddPolicy( Role.Admin, policy => policy.AddRequirements(new RoleRequirement(Role.Admin)))); }Role.cs
public static class Role { public const string Guest = "Guest"; public const string Admin = "Admin"; }RoleRequirement.cs
RoleRequirement.cs
public class RoleRequirement : IAuthorizationRequirement { public string[] Roles { get; } public RoleRequirement(params string[] roles) { this.Roles = roles; } }RoleAuthHandler.cs包含
RoleAuthHandler.cs contains
protected override Task HandleRequirementAsync( AuthorizationHandlerContext context, RoleRequirement requirement) { var wi = (WindowsIdentity)context.User.Identity; var groupSet = new HashSet<string>(); if (wi.Groups != null) { foreach (var group in wi.Groups) { groupSet.Add(group.Translate(typeof(NTAccount)).ToString()); } } string[] userRoles = roleService.GetRolesForGroup(groupSet); var intersectRoles = Enumerable.Intersect(userRoles, requirement.Roles, StringComparer.OrdinalIgnoreCase); if (intersectRoles.Count() > 0) { context.Succeed(requirement); } return Task.CompletedTask; }控制器类
[Authorize] [ApiController] [Route("[controller]")] public class InterestingController : ControllerBase { [HttpGet] public string Get() { return "Something Interesting"; } }推荐答案
@Sayah imad-感谢您的提醒.我在某处的某个帖子上看到了此解决方案,因此将其解散了,因为我正在寻找的信息是用户所属的组".我没有意识到的是,该信息在ClaimsIdentity中可用.您的提及使我三思而后行,我找到了答案:
@Sayah imad - Thanks for the reminder. I had seen this solution on a post somewhere and dismissed it because the information I was looking for was "what group does the user belong to". What I didn't realize was that the information was availabile in the ClaimsIdentity. Your mention, made me think twice about it and I found my answer:
protected override Task HandleRequirementAsync( AuthorizationHandlerContext context, RoleRequirement requirement) { var claimsIdentity = (ClaimsIdentity)context?.User.Identity; var userGroups = claimsIdentity.Claims .Where(x => x.Type.Contains("groupsid", StringComparison.OrdinalIgnoreCase)) .ToList(); if (userGroups == null || !userGroups.Any()) { return Task.CompletedTask; } var groupNames = new HashSet<string>(); foreach (var group in userGroups) { var groupName = new SecurityIdentifier(group.Value) .Translate(typeof(NTAccount)) .ToString(); groupNames.Add(groupName); } var userRoles = this.authenticationService.GetRoles(groupNames.ToArray()); // If the user is an Admin, always allow if (userRoles.Contains(Role.Admin)) { context.Succeed(requirement); return Task.CompletedTask; } var intersectingRoles = Enumerable.Intersect( userRoles, requirement?.Roles, StringComparer.OrdinalIgnoreCase); if (intersectingRoles?.Count() > 0) { context.Succeed(requirement); } return Task.CompletedTask; }更多推荐
自定义角色的Asp Net Core 3.1授权
发布评论