2014-07-17 15 views
6

Tôi đang phát triển một ứng dụng web với Asp.Net 5 MVC, mã định danh Owin và Oauth2 là kiểu xác thực.Giá trị yêu cầu bồi thường phức tạp trong .NET Framework với System.Security.Claims

Sau this guide có thêm một tuyên bố tùy chỉnh phức tạp Json serialized đến một instance của Microsoft.IdentityModel.Claims.ClaimsIdentity với thành công, tôi đã cố gắng để nhân rộng các ví dụ tương tự bằng cách sử dụng ClaimsIdentity trên namespace System.Security.Claims.

Thật không may, có vẻ như thêm complexClaim vào trường hợp ClaimsIdentity, thông tin loại lớp dẫn xuất bị mất và xác nhận quyền sở hữu được lưu trữ dưới dạng System.Security.Claims.Claim.

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

Khi tôi cố gắng lấy lại tuyên bố từ bản sắc, đúc nó để đến một ComplexClaim<UKPassport> Loại kết quả trong một giá trị null.

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

Ví dụ tương tự hoạt động hoàn hảo khi sử dụng Microsoft.IdentityModel.Claims.

Bất kỳ gợi ý nào?

Đây là mã hoàn chỉnh được chuyển:

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

Trả lời

7

này không được hỗ trợ cũng không đề nghị - yêu cầu là cặp/giá trị quan trọng - giữ chúng như đơn giản càng tốt.

Có một số hỗ trợ các lớp trong .NET mà không thể xử lý những gì bạn đang cố gắng để đạt được (SAM, CookieMiddleware vv) ..

cũng thấy ở đây http://leastprivilege.com/2012/10/08/custom-claims-principals-in-net-4-5/

+0

Tôi đã đọc một vài trong số các câu trả lời của bạn và blog của bạn, nhưng tôi vẫn không chắc chắn về một kịch bản được mô tả ở đây http://stackoverflow.com/questions/39380623/complex-claims-in-jwt nơi mà là một phần của bản sắc người dùng chúng tôi muốn có vai trò của mình cho các doanh nghiệp khác nhau. Điều đó dường như với tôi một phần thông tin về "người dùng là ai", nhưng nó sẽ đòi hỏi một JWT phức tạp mà bạn dường như không thích nhiều .. – iberodev

1

Dàn diễn viên trong GetPassport cố gắng chuyển đổi từ loại cơ sở Claim thành loại có nguồn gốc ComplexClaim<UKPassport> sẽ dẫn đến không có giá trị. Bạn cần phải viết một điều hành đúc để chuyển đổi từ Claim để UKPassport

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

GetPassport sẽ

private static UKPassport GetPassport(this ClaimsIdentity identity, string passportType) 
{ 
    return (UKPassport)identity.Claims.FirstOrDefault<Claim>(c => c.Type == @"http://it.test/currentpassport"); 
} 
Các vấn đề liên quan