Valores de declaração complexos no .NET Framework com System.Security.Claims
Estou desenvolvendo um aplicativo Web com o token de portador Asp.Net 5 MVC, Owin e Oauth2 como tipo de autenticação.
Segueeste guia que adiciona uma reivindicação complexa personalizada Json serializada a uma instância deMicrosoft.IdentityModel.Claims.ClaimsIdentity
com sucesso, tentei replicar o mesmo exemplo usando o métodoClaimIdentity noSystem.Security.Claims
namespace.
Infelizmente, parece que adicionar umcomplexClaim
aoClaimsIdentity
Por exemplo, as informações do tipo de classe derivada são perdidas e a declaração é armazenada como umSystem.Security.Claims.Claim
.
var complexClaim = new ComplexClaim<UKPassport>(@"http://it.test/currentpassport", passport);
var claims = new List<Claim>() { complexClaim };
identity.AddClaims(claims);
Quando tento recuperar a reivindicação de identidade, convertendo-a para umComplexClaim<UKPassport>
Digite resultados em um valor nulo.
var passportClaim = identity.Claims.FirstOrDefault<Claim>(c=>c.Type == @"http://it.test/currentpassport") as ComplexClaim<UKPassport>;
O mesmo exemplo funciona perfeitamente usandoMicrosoft.IdentityModel.Claims
.
Alguma dica?
Aqui está o código portado completo:
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);
}
}
}