。Net OpenId-ClaimsPrinciple。当前声明未找到自定义声明

问题描述 投票:0回答:1

由于我涉及很多项目,所以我不确定是否在哪里标记这个问题,但希望有人以前做过。

我有现有的框架4.6.2应用程序,负责将其从IdentityServer2 SAML令牌更新为OpenId / Bearer。我决定将IdentityServer4用于我的身份服务器,并利用以下内容在.net Framework 4.6.2中工作:

  • identityserver3.contrib.accesstokenvalidation(4.0.36)
    • 。net框架需要使用它来验证令牌
  • microsoft.owin.host.systemweb(4.0.1)
    • 在iis中运行owin
  • microsoft.owin.security.openidconnect(4.0.1)
    • openid
  • microsoft.owin.security.cookies(4.0.1)
    • MVC Cookie身份验证
  • kentor.owincookiesaver(1.1.1)
    • Katana cookie解决方法

我希望能够在身份声明列表中添加一些自定义声明,所以我有几行与此类似:

      SecurityTokenValidated = async (options) => {
        if (options.AuthenticationTicket.Identity.IsAuthenticated)
        {
          options.AuthenticationTicket.Identity.AddClaim(new Claim("claim1", "someValueUsedInThApp"));
        }
      }

然后我就可以通过Principle(System.Security.Claims.ClaimsPrincipal.Current.FindFirst(key))访问声明了。但是我遇到了其他一些问题,因为我不知道Framework和Core应用程序需要microsoft.owin.security.interop程序包才能共享cookie。我计划将此Cookie用于共享相同身份的多个应用。

所以我添加了:-microsoft.owin.security.interop(2.1.2)-在Framework和Core之间共享Cookie

共享的cookie看起来应该可以正常工作,但是我再也无法脱离“原则”了。该原理仅包含以下内容:sub,idp,amp,auth_time

我撞到了砖墙。我已经完成了所有关于丢失声明或变通办法的google尝试,但似乎无法找到指出这一点的“神奇”页面。

  • 我有JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();在我的代码中。
  • 我尝试尝试退出,然后在修改了身份后以编程方式返回到SecurityTokenValidated,希望该cookie将随着更新的声明而重新生成。 (奇怪的是,这似乎工作了一次,但我不知道为什么)。
  • 我看到很多关于使用option.ClaimActions.add(Claim)的自定义声明的参考,但是我认为这仅适用于核心运行的客户端。 (AddOpenIdConnect)

真的希望我只是想念一些东西而有人做到了。否则,我可能只是移到IdentityServer3,这很好,但我希望不要重做已完成的工作。

identityserver4 openid-connect identityserver3
1个回答
0
投票

[不确定您是否遇到了与我相同的问题(我正在与核心一起运行),但是为了能够从客户端读取角色声明,我必须将其包含在IdentityResource中。

public static IEnumerable<IdentityResource> Ids =>
    // https://github.com/IdentityServer/IdentityServer4/issues/1385#issuecomment-319761179
    // If you want the user's claims in the client, you need them in the id_token, so you need to add to the IdentityResource's UserClaims.

    new IdentityResource[]
    {
        new IdentityResources.OpenId(),
        new IdentityResources.Profile
        {
            UserClaims =
            {
                JwtClaimTypes.Role
            }
        },
        new IdentityResources.Phone()
    };

在这里我对此有所了解:Brock Allen's Github comment

对于动态解决方案(在id_token中带来一组用户声明或其他信息),您需要实现IProfileService。>>

/// <summary>
/// Custom implementation of a provider of profile data for the UserEndpoint
///
/// Often IdentityServer requires identity information about users when creating tokens or when handling requests to the userinfo or introspection endpoints.
/// By default, IdentityServer only has the claims in the authentication cookie to draw upon for this identity data.
/// It is impractical to put all of the possible claims needed for users into the cookie, so IdentityServer defines an extensibility point for allowing claims to be dynamically loaded as needed for a user.
/// This extensibility point is the IProfileService and it is common for a developer to implement this interface to access a custom database or API that contains the identity data for users.
/// </summary>
/// <remarks>http://docs.identityserver.io/en/latest/reference/profileservice.html</remarks>
public class ProfileService : IProfileService
{
    private readonly IUserClaimsPrincipalFactory<ApplicationUser> _claimsFactory;
    private readonly UserManager<ApplicationUser> _userManager;

    public ProfileService(UserManager<ApplicationUser> userManager, IUserClaimsPrincipalFactory<ApplicationUser> claimsFactory)
    {
        _userManager = userManager;
        _claimsFactory = claimsFactory;
    }

    public async Task GetProfileDataAsync(ProfileDataRequestContext context)
    {
        var sub = context.Subject.GetSubjectId();
        var user = await _userManager.FindByIdAsync(sub);
        var principal = await _claimsFactory.CreateAsync(user);

        var claims = principal.Claims.ToList();
        claims = claims.Where(claim => context.RequestedClaimTypes.Contains(claim.Type)).ToList();

        // Add custom claims in token here based on user properties or any other source
        //claims.Add(new Claim("employee_id", user.EmployeeId ?? string.Empty));

        context.IssuedClaims = claims;
    }

    public async Task IsActiveAsync(IsActiveContext context)
    {
        var sub = context.Subject.GetSubjectId();
        var user = await _userManager.FindByIdAsync(sub);
        context.IsActive = user != null;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.