【问题标题】:AuthorizeView Policy: Blazor Page not displayingAuthorizeView 策略:Blazor 页面未显示
【发布时间】:2020-07-05 20:28:15
【问题描述】:

IdentityServer 返回 AuthenticationScheme:Bearer 被禁止。

我检查了 AccessToken,它包含范围“account.read”但是 blazor 不显示页面

我错过了什么吗?

Startup.cs

        services.AddAuthorization(options =>
        {
            options.AddPolicy("Account", policy => policy.RequireClaim(JwtClaimTypes.Scope, "account"));
            options.AddPolicy("AccountWrite", policy => policy.RequireClaim(JwtClaimTypes.Scope, "account", "account.write"));
            options.AddPolicy("AccountRead", policy => policy.RequireClaim(JwtClaimTypes.Scope, "account", "account.read")); 
        });

Blazor 页面

<AuthorizeView> <p> you are logged in </p> <AuthorizeView>
<AuthorizeView Policy="AccountRead">
<p> you have account.read access </p>
</AuthorizeView>

【问题讨论】:

    标签: c# asp.net identityserver4 blazor blazor-server-side


    【解决方案1】:

    问题是由于当前不支持 Blazor 读取以数组形式发送的声明。

    例如用户:["c","r","u","d"]

    无法读取。

    要纠正这个问题,您需要添加 ClaimsPrincipalFactory

    例如

    public class ArrayClaimsPrincipalFactory<TAccount> : AccountClaimsPrincipalFactory<TAccount> where TAccount : RemoteUserAccount
    {
        public ArrayClaimsPrincipalFactory(IAccessTokenProviderAccessor accessor)
        : base(accessor)
        { }
    
    
        // when a user belongs to multiple roles, IS4 returns a single claim with a serialised array of values
        // this class improves the original factory by deserializing the claims in the correct way
        public async override ValueTask<ClaimsPrincipal> CreateUserAsync(TAccount account, RemoteAuthenticationUserOptions options)
        {
            var user = await base.CreateUserAsync(account, options);
    
            var claimsIdentity = (ClaimsIdentity)user.Identity;
    
            if (account != null)
            {
                foreach (var kvp in account.AdditionalProperties)
                {
                    var name = kvp.Key;
                    var value = kvp.Value;
                    if (value != null &&
                        (value is JsonElement element && element.ValueKind == JsonValueKind.Array))
                    {
                        claimsIdentity.RemoveClaim(claimsIdentity.FindFirst(kvp.Key));
    
                        var claims = element.EnumerateArray()
                            .Select(x => new Claim(kvp.Key, x.ToString()));
    
                        claimsIdentity.AddClaims(claims);
                    }
                }
            }
    
            return user;
        }
    }
    

    然后在您的程序/启动中注册它(取决于您是否使用 .core 托管),如下所示:

    builder.Services.AddOidcAuthentication(options =>
            {
                builder.Configuration.Bind("oidc", options.ProviderOptions);
            })
            .AddAccountClaimsPrincipalFactory<ArrayClaimsPrincipalFactory<RemoteUserAccount>>();
    

    【讨论】:

      【解决方案2】:

      这是框架中的全局问题,尚未修复。

      【讨论】:

      • 为了改进这个答案,如果你能为此添加一个引文,并在你的答案中引用相关部分,那将会很有用
      猜你喜欢
      • 2021-03-06
      • 1970-01-01
      • 2020-12-16
      • 1970-01-01
      • 1970-01-01
      • 2022-12-26
      • 1970-01-01
      • 1970-01-01
      • 2011-08-09
      相关资源
      最近更新 更多