我正在使用Asp.Net 5 MVC,Owin和Oauth2承载 token 作为身份验证类型开发Web应用程序。

this guide成功添加了将自定义复杂声明Json序列化到Microsoft.IdentityModel.Claims.ClaimsIdentity实例之后,我尝试使用System.Security.Claims命名空间上的ClaimsIdentity复制相同的示例。

不幸的是,似乎在complexClaim实例中添加了ClaimsIdentity,丢失了派生的类类型信息,并且将声明存储为System.Security.Claims.Claim

var complexClaim = new ComplexClaim<UKPassport>(@"http://it.test/currentpassport", passport);
var claims = new List<Claim>() { complexClaim };
identity.AddClaims(claims);

当我尝试从身份取回声明时,将其强制转换为ComplexClaim<UKPassport>类型会导致返回空值。
var passportClaim = identity.Claims.FirstOrDefault<Claim>(c=>c.Type == @"http://it.test/currentpassport") as ComplexClaim<UKPassport>;

使用Microsoft.IdentityModel.Claims可以完美地使用相同的示例。

有什么提示吗?

这是完整的移植代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using System.Security.Claims;

namespace ConsoleApplication1
{
    class Program {
    private static ClaimsIdentity identity = new ClaimsIdentity();

    static void Main(string[] args)
    {
        var oldPassport = CreatePassport();
        identity.AddPassport(oldPassport);

        var britishCitizen = identity.IsBritishCitizen();
        var hasExpired = identity.IsCurrentPassportExpired();
        Console.WriteLine(hasExpired);
        Console.ReadLine();
    }

    private static UKPassport CreatePassport()
    {
        var passport = new UKPassport(
            code: PassportCode.GBR,
            number: 123456789,
            expiryDate: DateTime.Now);

        return passport;
    }
}

    public static class ClaimsIdentityExtensions {
    public static void AddPassport(this ClaimsIdentity identity, UKPassport passport)
    {
        var complexClaim = new ComplexClaim<UKPassport>(@"http://it.test/currentpassport", passport);

        var claims = new List<Claim>() { complexClaim };
        identity.AddClaims(claims);
    }

    public static bool IsCurrentPassportExpired(this ClaimsIdentity identity)
    {
        var passport = GetPassport(identity, @"http://it.test/currentpassport");
        return DateTime.Now > passport.ExpiryDate;
    }

    public static bool IsBritishCitizen(this ClaimsIdentity identity)
    {
        var passport = GetPassport(identity, @"http://it.test/currentpassport");
        return passport.Code == PassportCode.GBR;
    }

    private static UKPassport GetPassport(this ClaimsIdentity identity, string passportType)
    {
        var passportClaim = identity.Claims.FirstOrDefault<Claim>(c=>c.Type == @"http://it.test/currentpassport") as ComplexClaim<UKPassport>;
        return passportClaim.Value;
    }
}

    public enum PassportCode
    {
        GBR,

        GBD,

        GBO,

        GBS,

        GBP,

        GBN
    }


    public class ComplexClaim<T> : Claim where T : ClaimValue
    {
        public ComplexClaim(string claimType, T claimValue)
            : this(claimType, claimValue, string.Empty)
        {
        }

        public ComplexClaim(string claimType, T claimValue, string issuer)
            : this(claimType, claimValue, issuer, string.Empty)
        {
        }

        public ComplexClaim(string claimType, T claimValue, string issuer, string originalIssuer)
            : base(claimType, claimValue.ToString(), claimValue.ValueType(), issuer, originalIssuer)
        {
        }

        public new T Value
        {
            get
            {
                return JsonConvert.DeserializeObject<T>(base.Value);
            }
        }
    }

    public class UKPassport : ClaimValue
    {
        public const string Name = "UKPassport";

        private readonly PassportCode code;
        private readonly int number;
        private readonly DateTime expiryDate;

        public UKPassport(PassportCode code, int number, DateTime expiryDate)
        {
            this.code = code;
            this.number = number;
            this.expiryDate = expiryDate;
        }

        public PassportCode Code { get { return this.code; } }
        public int Number { get { return this.number; } }
        public DateTime ExpiryDate { get { return this.expiryDate; } }

        public override string ValueType()
        {
            return @"http://it.test/currentpassport";
        }
    }

public abstract class ClaimValue {
    public abstract string ValueType();

    public override string ToString()
    {
        return JsonConvert.SerializeObject(this);
    }
}
}

最佳答案

不支持也不建议这样做-声明是键/值对-使其尽可能简单。

.NET中有许多支持类无法处理您要实现的目标(SAM,CookieMiddleware等)。

在这里也可以看到
http://leastprivilege.com/2012/10/08/custom-claims-principals-in-net-4-5/

关于c# - 带有System.Security.Claims的.NET Framework中的复杂声明值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24813709/

10-11 06:49