C# .NET Core 3.0索赔格式

C# .NET Core 3.0索赔格式,c#,.net-core,authorization,windows-authentication,C#,.net Core,Authorization,Windows Authentication,以前在.NET Framework中,我使用自定义RoleProvider与Windows身份验证一起提供针对当前主体的自定义角色,而不是使用Active Directory组 public class ClaimsTransformer : IClaimsTransformation { private readonly IConfiguration _configuration; public ClaimsTransformer(IConfiguration configu

以前在.NET Framework中,我使用自定义
RoleProvider
与Windows身份验证一起提供针对当前主体的自定义角色,而不是使用Active Directory组

public class ClaimsTransformer : IClaimsTransformation
{
    private readonly IConfiguration _configuration;

    public ClaimsTransformer(IConfiguration configuration)
    {
        _configuration = configuration;
    }
    public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
    {
        var claimsIdentity = (ClaimsIdentity)principal.Identity;
       // AppRole has two string props, Displayname and AdGroup. Get Adgroup from appsettings.json.
        AppRole customRole = new AppRole() 
        {  
            DisplayName =_configuration.GetSection("Roles")
                    .GetSection("CustomRole")
                    .GetSection("DisplayName").Value,
            AdGroup = _configuration.GetSection("Roles")
                    .GetSection("CustomRole")
                    .GetSection("AdGroup").Value
        };
        if (principal.IsInRole(customRole.AdGroup))
        {
            Claim customRoleClaim = new Claim(claimsIdentity.RoleClaimType, "CustomRole");
            claimsIdentity.AddClaim(customRoleClaim);
        }

        return Task.FromResult(principal);
    }
}
因此,我们的目标是能够使用装饰性的
[Authorize(Roles=”“)]
属性,其中角色来自数据库而不是active directory(或者两者结合使用就可以了)

为了在core中实现这一点,我认为我需要使用
iclaimsgransformation
来分配所讨论的角色声明

在这里,我只是想添加一个角色“Admin”,但是当我使用
[Authorize(Roles=“Admin”)]
时,我会得到一个403未经授权的响应

Startup.cs

services.AddRazorPages();
services.AddAuthentication(IISDefaults.AuthenticationScheme);
services.AddSingleton<IClaimsTransformation, ClaimsTransformer>();
-------
app.UseAuthorization();
            services.AddAuthorization(options =>
            {               
                options.FallbackPolicy = options.DefaultPolicy;
                options.AddPolicy("AdminOnly", policy => policy.RequireClaim(System.Security.Claims.ClaimTypes.Role, "Admin"));
            });
services.AddRazorPages();
服务.AddAuthentication(IISDefaults.AuthenticationScheme);
services.AddSingleton();
-------
app.UseAuthorization();
ClaimsTransformer.cs

    public class ClaimsTransformer : IClaimsTransformation
    {
        public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
        {
            var identity = (ClaimsIdentity)principal.Identity;
            var c = new Claim(identity.RoleClaimType, "Admin");
            identity.AddClaim(c);
            return await Task.FromResult(principal);
        }
    }
    public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
    {
        var identity = (WindowsIdentity)principal.Identity;

        Guid userGuid;

        SecurityIdentifier sid = identity.User;

        using (DirectoryEntry userDirectoryEntry = new DirectoryEntry("LDAP://<SID=" + sid.Value + ">"))
        {
            userGuid = userDirectoryEntry.Guid;
        }

        UserAccount user = null;

        if (userGuid != Guid.Empty)
            user = await db.UserAccounts.Where(x => x.GUID == userGuid).SingleOrDefaultAsync();

        if (user == null)
            return principal;

        if (user.Historic)
            return principal;


        var claims = new List<Claim>();
        foreach (var role in user?.UserAccountGroups)
        {
            claims.Add(new Claim(ClaimTypes.GroupSid, role.Group.Name));
        };

        identity.AddClaims(claims);

        return principal;
    }
public类claimtransformer:iclaims转换
{
公共异步任务TransformAsync(ClaimsPrincipal主体)
{
var identity=(ClaimsIdentity)principal.identity;
var c=新索赔(identity.RoleClaimType,“Admin”);
身份.补充索赔(c);
返回等待任务。FromResult(委托人);
}
}

令人恼火的是,当我调用
User.IsInRole()
时,这会起作用,当我检查声明时,我可以看到该组,因此正在添加该组,但它不适用于Authorize属性。如果您有任何建议,我们将不胜感激。

请使用
claimtransformer
和自定义
typefilteratAttribute

ClaimsTransformer.cs

    public class ClaimsTransformer : IClaimsTransformation
    {
        public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
        {
            var identity = (ClaimsIdentity)principal.Identity;
            var c = new Claim(identity.RoleClaimType, "Admin");
            identity.AddClaim(c);
            return await Task.FromResult(principal);
        }
    }
    public async Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
    {
        var identity = (WindowsIdentity)principal.Identity;

        Guid userGuid;

        SecurityIdentifier sid = identity.User;

        using (DirectoryEntry userDirectoryEntry = new DirectoryEntry("LDAP://<SID=" + sid.Value + ">"))
        {
            userGuid = userDirectoryEntry.Guid;
        }

        UserAccount user = null;

        if (userGuid != Guid.Empty)
            user = await db.UserAccounts.Where(x => x.GUID == userGuid).SingleOrDefaultAsync();

        if (user == null)
            return principal;

        if (user.Historic)
            return principal;


        var claims = new List<Claim>();
        foreach (var role in user?.UserAccountGroups)
        {
            claims.Add(new Claim(ClaimTypes.GroupSid, role.Group.Name));
        };

        identity.AddClaims(claims);

        return principal;
    }

我使用类似的方法根据用户的Active Directory组向用户提供自定义角色声明

public class ClaimsTransformer : IClaimsTransformation
{
    private readonly IConfiguration _configuration;

    public ClaimsTransformer(IConfiguration configuration)
    {
        _configuration = configuration;
    }
    public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
    {
        var claimsIdentity = (ClaimsIdentity)principal.Identity;
       // AppRole has two string props, Displayname and AdGroup. Get Adgroup from appsettings.json.
        AppRole customRole = new AppRole() 
        {  
            DisplayName =_configuration.GetSection("Roles")
                    .GetSection("CustomRole")
                    .GetSection("DisplayName").Value,
            AdGroup = _configuration.GetSection("Roles")
                    .GetSection("CustomRole")
                    .GetSection("AdGroup").Value
        };
        if (principal.IsInRole(customRole.AdGroup))
        {
            Claim customRoleClaim = new Claim(claimsIdentity.RoleClaimType, "CustomRole");
            claimsIdentity.AddClaim(customRoleClaim);
        }

        return Task.FromResult(principal);
    }
}
我在Blazor中使用了它,所以它可以像这样在Blazor组件中使用

要授权整个组件,请执行以下操作:

    @attribute [Authorize(Roles = "CustomRole")]
    <AuthorizeView Roles="CustomRole">
        <Authorized>You are authorized</Authorized>
    </AuthorizeView>
或授权部分组件:

    @attribute [Authorize(Roles = "CustomRole")]
    <AuthorizeView Roles="CustomRole">
        <Authorized>You are authorized</Authorized>
    </AuthorizeView>

你被授权了

我可以通过Startup.cs中的策略设置获得授权

services.AddRazorPages();
services.AddAuthentication(IISDefaults.AuthenticationScheme);
services.AddSingleton<IClaimsTransformation, ClaimsTransformer>();
-------
app.UseAuthorization();
            services.AddAuthorization(options =>
            {               
                options.FallbackPolicy = options.DefaultPolicy;
                options.AddPolicy("AdminOnly", policy => policy.RequireClaim(System.Security.Claims.ClaimTypes.Role, "Admin"));
            });

这似乎对AzureAD不起作用?