.net (索赔实体)重复的海关索赔

.net (索赔实体)重复的海关索赔,.net,.net-core,claims,.net,.net Core,Claims,brockallen说,“AuthenticateTasync()可能会被调用多次”,这可能是TransformAsync()被多次调用(在我的应用程序上调用两次)的原因 我不明白的是: 当我用参数构造ClaimsIdentity时,复制只发生在添加的声明上(“现在”和“繁荣”)。[见下面的代码1,图像1-A和图像1-B] 当我构建没有参数的ClaimsIdentity时,添加的声明(“now”和“boom”)不会重复。[见下面的代码2,图像2-A和图像2-B] 为什么添加的声明(现在和繁荣)是

brockallen说,“AuthenticateTasync()可能会被调用多次”,这可能是TransformAsync()被多次调用(在我的应用程序上调用两次)的原因

我不明白的是:

  • 当我用参数构造ClaimsIdentity时,复制只发生在添加的声明上(“现在”和“繁荣”)。[见下面的代码1图像1-A图像1-B]
  • 当我构建没有参数的ClaimsIdentity时,添加的声明(“now”和“boom”)不会重复。[见下面的代码2图像2-A图像2-B]
  • 为什么添加的声明(现在繁荣)是重复的,而其他/预定义的声明(nbfexpissaud等)不是重复的?[比较下面的图像1-A图像1-B]
  • 有人知道索赔实体为什么会这样吗


    更新问题:

    我不明白的是:

  • 当我用参数构造ClaimsIdentity时,复制只发生在添加的声明上(“现在”和“繁荣”)。[见下面的代码1图像1-A图像1-B]
    (已回答)
  • 当我构建没有参数的ClaimsIdentity时,添加的声明(“now”和“boom”)不会重复。[见下面的代码2图像2-A图像2-B]
    (已回答)
  • 为什么添加的声明(现在繁荣)是重复的,而其他/预定义的声明(nbfexpissaud等)不是重复的?[比较下面的图像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);
        }
    }
    
    class claimtransformer:iclaims转换
    {
    公共任务TransformAsync(ClaimsPrincipal主体)
    {
    var id=((ClaimsIdentity)principal.Identity);
    var ci=新的索赔实体(id.Claims、id.AuthenticationType、id.NameClaimType、id.RoleClaimType);
    添加声明(新声明(“now”,DateTime.now.ToString());
    ci.追加索赔(新索赔(“繁荣”、“呵呵”);
    var cp=新索赔(ci);
    返回任务.FromResult(cp);
    }
    }
    
    图像1-A

    图像1-B


    代码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);
        }
    }
    
    class claimtransformer:iclaims转换
    {
    公共任务TransformAsync(ClaimsPrincipal主体)
    {
    var ci=新的索赔实体();
    添加声明(新声明(“now”,DateTime.now.ToString());
    ci.追加索赔(新索赔(“繁荣”、“呵呵”);
    var cp=新索赔(ci);
    返回任务.FromResult(cp);
    }
    }
    
    图像2-A

    图像2-B

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

    回答问题2:
    我意识到复制永远不会发生,因为我总是创建一个新的ClaimsEntity,从不复制委托人的值。


    我通过在claimtransformer类中添加一个转换检查,并在DI中将其注册为AddScoped()而不是AddSingleton(),解决了重复的自定义声明问题

    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);
        }
    }
    
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            // other ConfigureServices() codes here
    
            services.AddScoped<IClaimsTransformation, ClaimsTransformer>();
    
            // other ConfigureServices() codes here
        }
    
        // Other Startup codes here
    }
    
    class claimtransformer:iclaims转换
    {
    私有布尔值已转换=假;
    公共任务TransformAsync(ClaimsPrincipal主体)
    {
    如果(!isTransformed)
    {
    var id=((ClaimsIdentity)principal.Identity).Clone();
    var ci=新的索赔实体(id);
    //在此处添加自定义索赔
    //例如,ci.AddClaim(新索赔(“boom”、“hehehe”);
    isTransformed=真;
    var cp=新索赔(ci);
    返回任务.FromResult(cp);
    }
    返回任务.FromResult(主体);
    }
    }
    
    Startup.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);
        }
    }
    
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            // other ConfigureServices() codes here
    
            services.AddScoped<IClaimsTransformation, ClaimsTransformer>();
    
            // other ConfigureServices() codes here
        }
    
        // Other Startup codes here
    }
    
    公共类启动
    {
    public void配置服务(IServiceCollection服务)
    {
    //此处的其他ConfigureServices()代码
    services.addScope();
    //此处的其他ConfigureServices()代码
    }
    //这里还有其他启动代码
    }
    
    检查pricinpal参数和DI的注册服务。声明已注册为DI作用域中的将是当前http请求中的某个对象。回答问题3:创建新标识时,所有声明都会自动从源复制。仅再次添加了“现在”和“繁荣”的声明。这些将发生两次,因为从源标识复制时它们已经在其中。其他声明(nbf、exp、iss…)如何?它们已经在里面了,但没有复制。当它第二次通过你的代码(代码1)时,声明“现在”和“爆炸”已经在id.claims中了。然后再次添加它们,以便复制它们。由于您没有显式地添加它们,因此不会复制其他对象。尝试添加行ci.AddClaim(新索赔(“nbf”、“1234”);然后nbf也将被复制:-)感谢@ChaimZonnenberg的例子这可能是索赔转换的一个错误(或不是)。我相信这与brockallen的问题有关。