I am developing a web application with an Asp.Net 5 MVC, Owin, and Oauth2 carrier token as an auth type.
Following this guide , which adds an individual complex Json application serialized to an instance of Microsoft.IdentityModel.Claims.ClaimsIdentity with success, I tried to replicate the same example using ClaimsIdentity in the System.Security.Claims .
Unfortunately, it seems that adding a complexClaim to the complexClaim instance, information about the type of the derived class is lost, and the requirement is saved as System.Security.Claims.Claim .
var complexClaim = new ComplexClaim<UKPassport>(@"http://it.test/currentpassport", passport); var claims = new List<Claim>() { complexClaim }; identity.AddClaims(claims);
When I try to return the application from the person, dropping it on the ComplexClaim<UKPassport> Type, you will get a zero value.
var passportClaim = identity.Claims.FirstOrDefault<Claim>(c=>c.Type == @"http://it.test/currentpassport") as ComplexClaim<UKPassport>;
Microsoft.IdentityModel.Claims works fine in the same example.
Any clues?
Here is the complete ported code:
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); } } }