2014-07-17 35 views
6

AMAA türü olarak Asp.Net 5 MVC, Owin ve Oauth2 taşıyıcı belirteci ile bir web uygulaması geliştiriyorum..NET Framework'te SystemSecurity.Claims ile Karmaşık Talep Değerleri

başarı ile Microsoft.IdentityModel.Claims.ClaimsIdentity örneğine tefrika özel kompleks iddiayı Json ekleyen this guide ardından, System.Security.Claims ad üzerinde ClaimsIdentity kullanarak aynı örneği çoğaltmak için çalıştık.

Unluckily, ClaimsIdentity örneğine complexClaim eklenmesi, türetilmiş sınıf türü bilgilerinin kaybolduğu ve iddianın System.Security.Claims.Claim olarak saklandığı anlaşılıyor.

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

Ben boş değer bir ComplexClaim<UKPassport> Tip sonuçlarına bunu döküm, kimliğinden iddiasını geri almak için denemek

.

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

Aynı örnek, Microsoft.IdentityModel.Claims kullanılarak mükemmel şekilde çalışır.

Herhangi bir ipucu? İşte

tam taşıdık kodudur:

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); 
    } 
} 
} 

cevap

7

Bu desteklenen ne de tavsiye edilmez - iddialar anahtar/değer çiftleri vardır - mümkün olduğunca basit tutun.

sen (vs SAM, CookieMiddleware) ulaşmak için ne çalışıyorsunuz işleyemez .NET sınıfları destekleyen bir dizi ..

Ayrıca bakınız edilir burada http://leastprivilege.com/2012/10/08/custom-claims-principals-in-net-4-5/

+0

Ben yanıtları ve blogunuzun birkaç okudum olacaktır UKPassport

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

ve GetPassport için Claim den dönüştürmek için bir döküm operatörü yazmaya gerek, ama yine de değilim http://stackoverflow.com/questions/39380623/complex-claims-in-jwt adresinde açıklanan bir senaryo hakkında emin olun, burada kullanıcı kimliğinin bir parçası olarak farklı işletmeler için rollerine sahip olmak istiyoruz. Bu bana "kim bir kullanıcı" ile ilgili bilgilerin bir parçası gibi görünüyor, ama çok fazla gibi görünmüyor karmaşık bir JWT gerektirecektir .. – iberodev

1

alçıda GetPassport taban türünden Claim türetme türetilmiş türetilmiş ComplexClaim<UKPassport> türetmek için null sonuçlanır. Sen

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