Valeurs de revendication complexes dans .NET Framework avec System.Security.Claims

Je développe une application Web avec un jeton porteur Asp.Net 5 MVC, Owin et Oauth2 en tant que type d’authentification.

Suite à ce guide qui ajoute une revendication complexe personnalisée Json sérialisée à une instance de Microsoft.IdentityModel.Claims.ClaimsIdentity , j’ai essayé de répliquer le même exemple à l’aide de ClaimsIdentity sur l’espace de noms System.Security.Claims .

Malheureusement, il semble que l’ajout d’une complexClaim à l’instance ClaimsIdentity la ClaimsIdentity informations de type de classe dérivée et la revendication soit stockée sous la forme d’une System.Security.Claims.Claim .

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

Lorsque j’essaie de récupérer la revendication d’identité, le transtypage vers un type ComplexClaim donne une valeur null.

 var passportClaim = identity.Claims.FirstOrDefault(c=>c.Type == @"http://it.test/currentpassport") as ComplexClaim; 

Le même exemple fonctionne parfaitement en utilisant Microsoft.IdentityModel.Claims .

Des allusions?

Voici le code complet porté:

 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(ssortingng[] 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(@"http://it.test/currentpassport", passport); var claims = new List() { 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, ssortingng passportType) { var passportClaim = identity.Claims.FirstOrDefault(c=>c.Type == @"http://it.test/currentpassport") as ComplexClaim; return passportClaim.Value; } } public enum PassportCode { GBR, GBD, GBO, GBS, GBP, GBN } public class ComplexClaim : Claim where T : ClaimValue { public ComplexClaim(ssortingng claimType, T claimValue) : this(claimType, claimValue, ssortingng.Empty) { } public ComplexClaim(ssortingng claimType, T claimValue, ssortingng issuer) : this(claimType, claimValue, issuer, ssortingng.Empty) { } public ComplexClaim(ssortingng claimType, T claimValue, ssortingng issuer, ssortingng originalIssuer) : base(claimType, claimValue.ToSsortingng(), claimValue.ValueType(), issuer, originalIssuer) { } public new T Value { get { return JsonConvert.DeserializeObject(base.Value); } } } public class UKPassport : ClaimValue { public const ssortingng 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 ssortingng ValueType() { return @"http://it.test/currentpassport"; } } public abstract class ClaimValue { public abstract ssortingng ValueType(); public override ssortingng ToSsortingng() { return JsonConvert.SerializeObject(this); } } } 

Ceci n’est ni pris en charge ni recommandé – les revendications sont des paires clé / valeur – gardez-les aussi simples que possible.

Il existe un certain nombre de classes de support dans .NET qui ne peuvent pas gérer ce que vous essayez d’atteindre (SAM, CookieMiddleware, etc.).

voir aussi ici http://leastprivilege.com/2012/10/08/custom-claims-principals-in-net-4-5/

La GetPassport dans GetPassport tente de convertir le type de base Claim en type dérivé ComplexClaim ce qui entraîne la valeur null. Vous devez écrire un opérateur de casting pour convertir de Claim en UKPassport

 public static explicit operator UKPassport(Claim c) { return (c == null ? null:JsonConvert.DeserializeObject (c.Value)); } 

et GetPassport sera

 private static UKPassport GetPassport(this ClaimsIdentity identity, ssortingng passportType) { return (UKPassport)identity.Claims.FirstOrDefault(c => c.Type == @"http://it.test/currentpassport"); }