在System.Security.Claims .NET框架复杂声明值 [英] Complex Claim Values in .NET Framework with System.Security.Claims

查看:2770
本文介绍了在System.Security.Claims .NET框架复杂声明值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发展与Asp.Net MVC 5,Owin和承载的OAuth2令牌认证类型的web应用程序



以下的,增加了自定义复杂的索赔JSON序列为> Microsoft.IdentityModel.Claims.ClaimsIdentity 成功,我已经尝试使用的 ClaimsIdentity 上的 System.Security.Claims 命名空间。



不幸,似乎增加了 complexClaim ClaimsIdentity 例如,派生类类型的信息丢失,索赔存储为 System.Security.Claims.Claim

  VAR complexClaim =新ComplexClaim< UKPassport>(@HTTP://it.test/currentpassport,护照); 
变种索赔=新的List<权利要求GT;(){} complexClaim;
identity.AddClaims(索赔);

当我试图找回从认同了这一说法,它转换为一个 ComplexClaim< UKPassport方式> 键入一个空值结果。

  VAR passportClaim = identity.Claims。 FirstOrDefault&所述;如权利要求>(C => c.Type == @的http://it.test/currentpassport)作为ComplexClaim&所述; UKPassport取代; 



同样的例子完美的作品使用 Microsoft.IdentityModel.Claims



任何提示



下面是完整移植的代码:

 使用系统; 
使用System.Collections.Generic;
使用System.Linq的;
使用System.Text;使用System.Threading.Tasks
;
使用Newtonsoft.Json;使用System.Security.Claims
;

命名ConsoleApplication1
{
类节目{
私有静态ClaimsIdentity身份=新ClaimsIdentity();

静态无效的主要(字串[] args)
{
VAR oldPassport = CreatePassport();
identity.AddPassport(oldPassport);

VAR britishCitizen = identity.IsBritishCitizen();
VAR hasExpired = identity.IsCurrentPassportExpired();
Console.WriteLine(hasExpired);
到Console.ReadLine();
}

私有静态UKPassport CreatePassport()
{
变种护照=新UKPassport(
码:PassportCode.GBR,
编号: 123456789,
expiryDate:DateTime.Now);

返回护照;
}
}

公共静态类ClaimsIdentityExtensions {
公共静态无效AddPassport(这ClaimsIdentity身份,UKPassport护照)
{
变种complexClaim =新ComplexClaim< UKPassport>(@HTTP://it.test/currentpassport,护照);

变种索赔=新的List<权利要求GT;(){} complexClaim;
identity.AddClaims(索赔);
}

公共静态布尔IsCurrentPassportExpired(此ClaimsIdentity身份)
{
VAR护照= GetPassport(身份证,@HTTP://it.test/currentpassport );
返回DateTime.Now> passport.ExpiryDate;
}

公共静态布尔IsBritishCitizen(此ClaimsIdentity身份)
{
VAR护照= GetPassport(身份证,@HTTP://it.test/currentpassport );
返回passport.Code == PassportCode.GBR;
}

私有静态UKPassport GetPassport(这ClaimsIdentity身份,串passportType)
{
VAR passportClaim = identity.Claims.FirstOrDefault<权利要求GT;(C => c.Type == @HTTP://it.test/currentpassport)作为ComplexClaim< UKPassport取代;
返回passportClaim.Value;
}
}

公共枚举PassportCode
{
GBR,

GBD,

GBO,

GBS,

英镑,

GBN
}


公共类ComplexClaim< T> :索赔其中T:ClaimValue
{
公共ComplexClaim(字符串claimType,T claimValue)
:这(claimType,claimValue,的String.Empty)
{
$} b
$ b酒店的公共ComplexClaim(字符串claimType,T claimValue,串发行人)
:这(claimType,claimValue,发行人的String.Empty)
{
}

公共ComplexClaim(字符串claimType,T claimValue,发行人的字符串,字符串originalIssuer)
:基地(claimType,claimValue.ToString(),claimValue.ValueType(),发行人,originalIssuer)
$ { b $ b}

公开新的T值
{
得到
{
返回JsonConvert.DeserializeObject< T>(base.Value);
}
}
}

公共类UKPassport:ClaimValue
{
公共常量字符串名称=UKPassport;

私人只读PassportCode代码;
私人只读INT编号;
私人只读的DateTime expiryDate;

公共UKPassport(PassportCode代码,INT编号,日期expiryDate)
{
this.code =代码;
this.number =数字;
this.expiryDate = expiryDate;
}

公共PassportCode代码{{返回this.code; }}
公众诠释号码{{返回this.number; }}
公众的DateTime ExpiryDate {{返回this.expiryDate; }}

公众覆盖字符串值类型()
{
返回@HTTP://it.test/currentpassport
}
}

公共抽象类ClaimValue {
公共抽象的字符串值类型();

公共重写字符串的ToString()
{
返回JsonConvert.SerializeObject(本);
}
}
}


解决方案

这是不支持也不推荐 - 说法是键/值对 - 让他们尽可能的简单



有一些在.NET支持类无法处理你正在努力实现的(在SAM,CookieMiddleware等)什么。



又见这里
http://leastprivilege.com/2012/10/08/custom-claims-principals-in-net -4-5 /


I'm developing a web app with Asp.Net 5 MVC, Owin and Oauth2 bearer token as auth type.

Following this guide that adds a custom complex claim Json serialized to an instance of Microsoft.IdentityModel.Claims.ClaimsIdentity with success, I've tried to replicate the same example using the ClaimsIdentity on the System.Security.Claims namespace.

Unluckily, it seems that adding a complexClaim to the ClaimsIdentity instance, the derived class type information is lost, and the claim is stored as a 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 get back the claim from identity, casting it to to a ComplexClaim<UKPassport> Type results in a null value.

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

The same example works perfectly using Microsoft.IdentityModel.Claims.

Any hints?

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

解决方案

This is not supported nor recommended - claims are key / value pairs - keep them as simple as possible.

There are a number of supporting classes in .NET that can't handle what you are trying to achieve (the SAM, CookieMiddleware etc)..

see also here http://leastprivilege.com/2012/10/08/custom-claims-principals-in-net-4-5/

这篇关于在System.Security.Claims .NET框架复杂声明值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆