簡體   English   中英

將 Okta 聲明映射到 .NET Blazor 中的角色

[英]Mapping Okta Claims to Roles in .NET Blazor

我有一個 .NET 5.0(從 .NET 核心升級)托管的 Blazor 解決方案與 Okta 集成。

我可以毫無問題地登錄,但是當我被重定向回我的應用程序時,我遇到了將角色映射到聲明的問題。


   Unhandled exception rendering component: InvalidOperation_EnumFailedVersion

System.InvalidOperationException: InvalidOperation_EnumFailedVersion

  at System.Collections.Generic.List`1.Enumerator[[System.Security.Claims.Claim, System.Security.Claims, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].MoveNextRare()

  at System.Collections.Generic.List`1.Enumerator[[System.Security.Claims.Claim, System.Security.Claims, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a]].MoveNext()

  at System.Security.Claims.ClaimsIdentity.FindAll(Predicate`1 match)+MoveNext()

  at WFBC.Client.RolesClaimsPrincipalFactory.CreateUserAsync(RemoteUserAccount account, RemoteAuthenticationUserOptions options)

  at Microsoft.AspNetCore.Components.WebAssembly.Authentication.RemoteAuthenticationService`3.<GetAuthenticatedUser>d__26[[Microsoft.AspNetCore.Components.WebAssembly.Authentication.RemoteAuthenticationState, Microsoft.AspNetCore.Components.WebAssembly.Authentication, Version=5.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[Microsoft.AspNetCore.Components.WebAssembly.Authentication.RemoteUserAccount, Microsoft.AspNetCore.Components.WebAssembly.Authentication, Version=5.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60],[Microsoft.AspNetCore.Components.WebAssembly.Authentication.OidcProviderOptions, Microsoft.AspNetCore.Components.WebAssembly.Authentication, Version=5.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]].MoveNext()

錯誤在這里被拋出:

namespace WFBC.Client
{
    public class RolesClaimsPrincipalFactory : AccountClaimsPrincipalFactory<RemoteUserAccount>
    {
        public RolesClaimsPrincipalFactory(IAccessTokenProviderAccessor accessor) : base(accessor)
        {
        }

        public override async ValueTask<ClaimsPrincipal> CreateUserAsync(RemoteUserAccount account, RemoteAuthenticationUserOptions options)
        {
            var user = await base.CreateUserAsync(account, options);
            if (!user.Identity.IsAuthenticated)
            {
                return user;
            }

            var identity = (ClaimsIdentity)user.Identity;
            var roleClaims = identity.FindAll(claim => claim.Type == "groups");
            if (roleClaims == null || !roleClaims.Any())
            {
                return user;
            }

            foreach (var existingClaim in roleClaims)
            {
                identity.RemoveClaim(existingClaim);
            }

            var rolesElem = account.AdditionalProperties["groups"];
            if (!(rolesElem is JsonElement roles))
            {
                return user;
            }

            if (roles.ValueKind == JsonValueKind.Array)
            {
                foreach (var role in roles.EnumerateArray())
                {
                    identity.AddClaim(new Claim(options.RoleClaim, role.GetString()));
                }
            }
            else
            {
                identity.AddClaim(new Claim(options.RoleClaim, roles.GetString()));
            }

            return user;
        }
    }
}

這個 foreach 循環似乎是異常的來源:

            foreach (var existingClaim in roleClaims)
            {
                identity.RemoveClaim(existingClaim);
            }

我能找到的唯一信息似乎指向試圖修改 IEnumerable,但在這種情況下我不是。 roleClaims 是 IEnumerable,但 identity 是 ClaimsIdentity object。

這是以前工作的,所以我不確定它是由 .NET 5.0 升級還是 Okta nuget 包的一些更改引起的。 不幸的是 Blazor 調試到客戶端項目還遠未准備好生產,目前不適合我。

試試這個代碼:

public class RolesClaimsPrincipalFactory : AccountClaimsPrincipalFactory<RemoteUserAccount>
    {
        public RolesClaimsPrincipalFactory(IAccessTokenProviderAccessor accessor) : base(accessor)
        {
        }

        public override async ValueTask<ClaimsPrincipal> CreateUserAsync(RemoteUserAccount account, RemoteAuthenticationUserOptions options)
        {
            var user = await base.CreateUserAsync(account, options);
            if (user.Identity.IsAuthenticated)
            {
                var identity = (ClaimsIdentity)user.Identity;
                var roleClaims = identity.FindAll(identity.RoleClaimType);
                if (roleClaims != null && roleClaims.Any())
                {
                    foreach (var existingClaim in roleClaims)
                    {
                        identity.RemoveClaim(existingClaim);
                    }

                    var rolesElem = account.AdditionalProperties[identity.RoleClaimType];
                    if (rolesElem is JsonElement roles)
                    {
                        if (roles.ValueKind == JsonValueKind.Array)
                        {
                            foreach (var role in roles.EnumerateArray())
                            {
                                identity.AddClaim(new Claim(options.RoleClaim, role.GetString()));
                            }
                            
                        }
                        else
                        {
                            identity.AddClaim(new Claim(options.RoleClaim, roles.GetString()));
                        }
                    }
                }
            }

            return user;
        }
    }

不要忘記.AddAccountClaimsPrincipalFactory<RolesClaimsPrincipalFactory>(); 在 Program.Main

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM