(ClaimsIdentity)重复的自定义声明

时间:2018-08-07 05:16:45

标签: .net .net-core claims

在brockallen的article中,他说“ AuthenticateAsync()可能被多次调用”,这可能是TransformAsync()被多次调用的原因(在我的应用程序中两次)。

我没有得到的是:

  1. 当我构造带有参数的ClaimsIdentity时,复制仅发生在添加的声明(“ now”和“ boom”)上。 [请参见下面的代码1 图像1-A 图像1-B ]
  2. 当我构造ClaimsIdentity WITHOUT参数时,添加的声明(“ now”和“ boom”)不会重复。 [请参见下面的代码2 图像2-A 图像2-B ]
  3. 添加的声明(现在景气)如何重复,而其他/预定义的声明( nbf exp iss aud 等)不是吗? [比较下面的图像1-A 图像1-B ]

有人知道为什么ClaimsIdentity会这样吗?


更新的问题:

我没有得到的是:

  1. 当我构造带有参数的ClaimsIdentity时,复制仅发生在添加的声明(“ now”和“ boom”)上。 [请参见下面的代码1 图像1-A 图像1-B ]
    (已回答)
  2. 当我构造无参数的ClaimsIdentity时,添加的声明(“ now”和“ boom”)不会重复。 [请参见下面的代码2 图片2-A 图片2-B ]
    (已回答)
  3. 添加的声明(现在景气)如何重复,而其他/预定义的声明( nbf exp iss aud 等)不是吗? [比较下面的图像1-A 图像1-B ]
    (未回答,但下面发布了替代代码)

代码1

class ClaimsTransformer : IClaimsTransformation
{
    public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
    {
        var id = ((ClaimsIdentity)principal.Identity);
        var ci = new ClaimsIdentity(id.Claims, id.AuthenticationType, id.NameClaimType, id.RoleClaimType);

        ci.AddClaim(new Claim("now", DateTime.Now.ToString()));
        ci.AddClaim(new Claim("boom", "hehehe"));

        var cp = new ClaimsPrincipal(ci);

        return Task.FromResult(cp);
    }
}

图像1-A

enter image description here

图片1-B

enter image description here


代码2

class ClaimsTransformer : IClaimsTransformation
{
    public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
    {
        var ci = new ClaimsIdentity();

        ci.AddClaim(new Claim("now", DateTime.Now.ToString()));
        ci.AddClaim(new Claim("boom", "hehehe"));

        var cp = new ClaimsPrincipal(ci);

        return Task.FromResult(cp);
    }
}

图片2-A

enter image description here

图片2-B

enter image description here

2 个答案:

答案 0 :(得分:2)

回答问题1:
我意识到重复的发生是因为我要复制主体的值,并返回带有已添加的自定义声明的返回值。

回答问题2:
我意识到复制永远不会发生,因为我总是在创建一个新的ClaimsIdentity,并且从不复制主体的值。

答案 1 :(得分:0)

我通过在 ClaimsTransformer 类中添加转换检查并在DI中将其注册为 AddScoped()而不是AddSingleton()来解决重复的自定义声明问题。 / p>

ClaimsTransformer.cs

class ClaimsTransformer : IClaimsTransformation
{
    private bool isTransformed = false;

    public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
    {
        if (!isTransformed)
        {
            var id = ((ClaimsIdentity)principal.Identity).Clone();
            var ci = new ClaimsIdentity(id);

            // add custom claims here
            // e.g. ci.AddClaim(new Claim("boom", "hehehe"));

            isTransformed = true;

            var cp = new ClaimsPrincipal(ci);
            return Task.FromResult(cp);
        }

        return Task.FromResult(principal);
    }
}

Startup.cs

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // other ConfigureServices() codes here

        services.AddScoped<IClaimsTransformation, ClaimsTransformer>();

        // other ConfigureServices() codes here
    }

    // Other Startup codes here
}