【问题标题】:Windows Authentication Asp.net core 2 database role authorizationWindows Authentication Asp.net core 2 数据库角色授权
【发布时间】:2018-11-17 20:35:55
【问题描述】:

我正在开发一个使用 Asp.Net Core 2.1 和 Windows 身份验证的 Intranet 应用程序。我从 IIS 获得通过就好了,但我想使用存储在数据库中的角色进行授权。

我有一个 IClaimsTransformeration 类,它根据 LAN Id 从数据库中获取角色,并使用角色键将它们添加到声明列表中。

public class MyClaimsTransformer : IClaimsTransformation
{
    private readonly IUnitOfWorkMtuSecurity _unitOfWork;

    public MyClaimsTransformer(IUnitOfWorkMtuSecurity unitOfWork)
    {
        _unitOfWork = unitOfWork;
    }

    // Each time HttpContext.AuthenticateAsync() or HttpContext.SignInAsync(...) is called the claims transformer is invoked. So this might be invoked multiple times. 
    public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
    {
        var identity = principal.Identities.FirstOrDefault(x => x.IsAuthenticated);
        if (identity == null) return principal;

        //var user = await _userManager.GetUserAsync(principal);
        var user = identity.Name;
        if (user == null) return principal;

        //Get user with roles from repository.
        var dbUser = _unitOfWork.UserInformations.GetUserWithRoles(user);

        // Inject DbRoles into Claims list
        foreach (var role in dbUser.UserInformationUserRoles.Select((r=>r.UserRole)))
        {
            var claim = new Claim(ClaimTypes.Role, role.Name);
            identity.AddClaim(claim);
        }

        return new ClaimsPrincipal(identity);
    }  
}

我在 startup.cs 中将 IClaimsTransformation 添加到我的服务中

services.AddScoped<IClaimsTransformation, MyClaimsTransformer>();

然后我将属性添加到我的控制器中

[Authorize(Roles = "Administrator")]

当我运行我的应用程序时,我收到以下错误:

处理请求时发生未处理的异常。 InvalidOperationException:没有指定 authenticationScheme,也没有找到 DefaultForbidScheme。 Microsoft.AspNetCore.Authentication.AuthenticationService.ForbidAsync(HttpContext context, string scheme, AuthenticationProperties properties)

在 startup.cs 中,我将以下内容添加到服务中

services.AddAuthentication(IISDefaults.AuthenticationScheme);

这消除了错误,但无论如何我都会收到 403 错误。

您无权查看此页面。 HTTP 错误 403

当我查看 MyClaimsTransformer 的返回值时,我可以看到管理员角色已添加到声明列表中,但无论如何我都会收到 403 错误。

有人对我缺少的东西有什么建议吗?

如果我在视图中使用以下语法,它将在视图级别工作:

 @if (User.HasClaim("http://schemas.microsoft.com/ws/2008/06/identity/claims/role", "Administrator"))
                    {
                <li><a asp-area="" asp-controller="UserInformationAdmin" asp-action="Index">Admin</a></li>
                     } 

我必须指定整个架构 url。

【问题讨论】:

    标签: c# asp.net-mvc authorization authorize-attribute asp.net-core-2.1


    【解决方案1】:

    ClaimIdentity 的 RoleClaimType 为“http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid”

    它必须是“http://schemas.microsoft.com/ws/2008/06/identity/claims/role”的 RoleClaimType

    由于这是一个只读属性,我更改了 TransformAsync 方法以创建新的 ClaimsPrincipal,而不是尝试将数据库角色添加到现有声明。我的应用程序不需要任何 AD 组,因此它只使用 windows 进行身份验证。下面的代码似乎工作。

    public class MyClaimsTransformer : IClaimsTransformation
    {
        private readonly IUnitOfWorkSecurity _unitOfWork;
    
        public MyClaimsTransformer(IUnitOfWorkSecurity unitOfWork)
        {
            _unitOfWork = unitOfWork;
        }
    
        // Each time HttpContext.AuthenticateAsync() or HttpContext.SignInAsync(...) is called the claims transformer is invoked. So this might be invoked multiple times. 
        public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
        {
            var identity = principal.Identities.FirstOrDefault(x => x.IsAuthenticated);
            if (identity == null) return principal;
    
            var user = identity.Name;
            if (user == null) return principal;
    
            //Get user with roles from repository.
            var dbUser = _unitOfWork.UserInformations.GetUserWithRoles(user);
    
            var claims = new List<Claim>();
    
            //The claim identity uses a claim with the claim type below to determine the name property.
            claims.Add(new Claim(@"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", user, "Name"));
    
            //todo: We should probably create a cache for this
            // Get User Roles from database and add to list of claims.
            foreach (var role in dbUser.UserInformationUserRoles.Select((r=>r.UserRole)))
            {
                claims.Add(new Claim(ClaimTypes.Role, role.Name));
            }
    
            var newClaimsIdentity = new ClaimsIdentity(claims,"Kerberos","", "http://schemas.microsoft.com/ws/2008/06/identity/claims/role");
    
            var newClaimsPrincipal = new ClaimsPrincipal(newClaimsIdentity);
    
            return new ClaimsPrincipal(newClaimsPrincipal);
        }  
    }
    

    【讨论】:

      猜你喜欢
      • 2021-09-04
      • 2017-12-01
      • 2020-05-18
      • 1970-01-01
      • 2023-03-19
      • 1970-01-01
      • 1970-01-01
      • 2018-08-05
      • 1970-01-01
      相关资源
      最近更新 更多