ClaimKeyValue 模块初步 1
This commit is contained in:
		
							parent
							
								
									110db553fd
								
							
						
					
					
						commit
						e06576fa46
					
				
							
								
								
									
										17
									
								
								Falcon.SugarApi/ClaimTicket/ClaimKeyValue.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								Falcon.SugarApi/ClaimTicket/ClaimKeyValue.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
			
		||||
namespace Falcon.SugarApi.ClaimTicket
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 存储claim的结构
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class ClaimKeyValue
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 存储Type
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public string Key { get; set; }
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 存储值
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public string Value { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										54
									
								
								Falcon.SugarApi/ClaimTicket/ClaimTicketModelBinding.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								Falcon.SugarApi/ClaimTicket/ClaimTicketModelBinding.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,54 @@
 | 
			
		||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Falcon.SugarApi.ClaimTicket
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 模型绑定
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class ClaimTicketModelBinding:IModelBinder
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 票据创建器
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public ITicketBuilder Builter { get; set; }
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 配置
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public ClaimTicketOptions Options { get; set; }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 通过票据创建器创建模型绑定
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="builter"></param>
 | 
			
		||||
        /// <param name="options"></param>
 | 
			
		||||
        public ClaimTicketModelBinding(ITicketBuilder builter,ClaimTicketOptions options) {
 | 
			
		||||
            Builter = builter;
 | 
			
		||||
            this.Options = options;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Task IModelBinder.BindModelAsync(ModelBindingContext bindingContext) {
 | 
			
		||||
            if(bindingContext.ModelType != typeof(UserTicket)) {
 | 
			
		||||
                return FailBind(bindingContext);
 | 
			
		||||
            }
 | 
			
		||||
            var token = bindingContext.ValueProvider.GetValue(this.Options.HttpHeaderKey).ToString();
 | 
			
		||||
            if(token.IsNullOrEmpty()) {
 | 
			
		||||
                token = bindingContext.HttpContext.Request.Headers[this.Options.HttpHeaderKey].ToString();
 | 
			
		||||
            }
 | 
			
		||||
            var model = this.Builter.GetUser(token);
 | 
			
		||||
            if(model == null) {
 | 
			
		||||
                return FailBind(bindingContext);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            bindingContext.Model = model;
 | 
			
		||||
            bindingContext.Result = ModelBindingResult.Success(bindingContext.Model);
 | 
			
		||||
 | 
			
		||||
            return Task.CompletedTask;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static Task FailBind(ModelBindingContext bindingContext) {
 | 
			
		||||
            bindingContext.Result = ModelBindingResult.Failed();
 | 
			
		||||
            return Task.CompletedTask;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,24 @@
 | 
			
		||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
 | 
			
		||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Binders;
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace Falcon.SugarApi.ClaimTicket
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// ClaimTicket模型绑定提供器
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class ClaimTicketModelBindingProvider:IModelBinderProvider
 | 
			
		||||
    {
 | 
			
		||||
        IModelBinder? IModelBinderProvider.GetBinder(ModelBinderProviderContext context) {
 | 
			
		||||
            if(context == null) {
 | 
			
		||||
                throw new ArgumentNullException(nameof(context));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(context.Metadata.ModelType == typeof(UserTicket)) {
 | 
			
		||||
                return new BinderTypeModelBinder(typeof(ClaimTicketModelBinding));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										27
									
								
								Falcon.SugarApi/ClaimTicket/ClaimTicketOptions.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								Falcon.SugarApi/ClaimTicket/ClaimTicketOptions.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,27 @@
 | 
			
		||||
using Falcon.SugarApi.Encryption;
 | 
			
		||||
 | 
			
		||||
namespace Falcon.SugarApi.ClaimTicket
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 票据系统配置
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class ClaimTicketOptions
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 加密键
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public string EncryptionKey { get; set; } = "E9319792CB7249AD8E432000E9F2FE7A";
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// http头票据key
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public string HttpHeaderKey { get; set; } = "_authUserTicket";
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 安全加密组件
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public IEncryption Encryption { get; set; }
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 序列化组件
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public ISerialize JsonSerialize { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										25
									
								
								Falcon.SugarApi/ClaimTicket/ITicketBuilder.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								Falcon.SugarApi/ClaimTicket/ITicketBuilder.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,25 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Security.Claims;
 | 
			
		||||
 | 
			
		||||
namespace Falcon.SugarApi.ClaimTicket
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 票据生成接口
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public interface ITicketBuilder
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 根据用户生成票据
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="userTicket">用户票据</param>
 | 
			
		||||
        /// <returns>ticket</returns>
 | 
			
		||||
        string? GetTicket(UserTicket userTicket);
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 通过ticket获取用户
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="ticket">token</param>
 | 
			
		||||
        /// <returns>声明组</returns>
 | 
			
		||||
        UserTicket? GetUser(string ticket);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										180
									
								
								Falcon.SugarApi/ClaimTicket/Readme.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										180
									
								
								Falcon.SugarApi/ClaimTicket/Readme.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,180 @@
 | 
			
		||||
## 客户凭据   Falcon.SugarApi.ClaimTicket.ClaimTicket
 | 
			
		||||
 | 
			
		||||
### 1、添加ClaimTicket支持。   
 | 
			
		||||
  是否使用ClaimTicket由插件自行决定。   
 | 
			
		||||
  如果插件需要使用ClaimTicket,按如下方式在插件服务配置中添加。  
 | 
			
		||||
~~~C#
 | 
			
		||||
public class ServicePlugin:IServicePlugin
 | 
			
		||||
{
 | 
			
		||||
    IServiceCollection IServicePlugin.AddServices(IServiceCollection services,IConfiguration configuration) {
 | 
			
		||||
        //注入使用ClaimTicket的控制器
 | 
			
		||||
        services.AddPluginsController(this.GetType().Assembly);
 | 
			
		||||
        //添加ClaimTicket服务支持
 | 
			
		||||
        services.AddClaimTicket();
 | 
			
		||||
        return services;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
~~~   
 | 
			
		||||
 | 
			
		||||
### 2、控制器注入  
 | 
			
		||||
  要完成用户的登录,认证和绑定工作需要注入ITicketBuilder接口,这个接口在上面的services.AddClaimTicket()中已经完成注入。  
 | 
			
		||||
  下面是在HomeController控制器中注入ITicketBuilder的示例。  
 | 
			
		||||
~~~C#   
 | 
			
		||||
 | 
			
		||||
public ITicketBuilder TicketBuilder { get; set; }
 | 
			
		||||
 | 
			
		||||
public HomeController(IServiceProvider service) : base(service) {
 | 
			
		||||
    this.TicketBuilder = service.GetRequiredService<ITicketBuilder>();
 | 
			
		||||
}
 | 
			
		||||
~~~   
 | 
			
		||||
### 3、用户登录。
 | 
			
		||||
  插件需要自行完成用户认证工作,示例代码如下。   
 | 
			
		||||
~~~c#
 | 
			
		||||
[HttpGet]
 | 
			
		||||
public string Login(string username) {
 | 
			
		||||
    //验证用户有效性,自行调用数据库进行验证。
 | 
			
		||||
 | 
			
		||||
    //如果通过验证,生成用户票据
 | 
			
		||||
    var user = new UserTicket(
 | 
			
		||||
            //添加用户名
 | 
			
		||||
            new Claim("name",username),
 | 
			
		||||
            //添加其他必要的声明
 | 
			
		||||
            new Claim("role","admin")
 | 
			
		||||
    );
 | 
			
		||||
    var ticket = this.TicketBuilder.GetTicket(user);
 | 
			
		||||
    return ticket ?? "";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
~~~
 | 
			
		||||
客户端在收到返回的票据后自行保管票据。   
 | 
			
		||||
 | 
			
		||||
### 4、验证用户   
 | 
			
		||||
实例代码如下:
 | 
			
		||||
~~~c#   
 | 
			
		||||
[HttpGet]
 | 
			
		||||
public string ViewUser(string ticket) {
 | 
			
		||||
    //通过票据获取用户
 | 
			
		||||
    var cs = this.TicketBuilder.GetUser(ticket);
 | 
			
		||||
    if(cs == null) {
 | 
			
		||||
        return "TicketBuilder.GetUser 返回空";
 | 
			
		||||
    }
 | 
			
		||||
    StringBuilder sb = new();
 | 
			
		||||
    //轮训票据生成获取登录信息
 | 
			
		||||
    foreach(var i in cs.Claims) {
 | 
			
		||||
        sb.AppendLine($"type:{i.Type},Val:{i.Value}");
 | 
			
		||||
    }
 | 
			
		||||
    return sb.ToString();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
~~~   
 | 
			
		||||
### 5、绑定用户    
 | 
			
		||||
示例代码如下:
 | 
			
		||||
~~~c#
 | 
			
		||||
[HttpGet]
 | 
			
		||||
public string Viewbind(string _authUserTicket,[FromHeader] UserTicket user) {
 | 
			
		||||
    StringBuilder sb = new();
 | 
			
		||||
    foreach(var i in user.Claims) {
 | 
			
		||||
        sb.AppendLine($"type:{i.Type},Val:{i.Value}");
 | 
			
		||||
    }
 | 
			
		||||
    return sb.ToString();
 | 
			
		||||
}
 | 
			
		||||
~~~    
 | 
			
		||||
一般客户端通过HTTP头参数_authUserTicket提交用户凭据,这个例子中为了方便通过get参数提交票据,控制器可以自动将其绑定在UserTicket对象中。  
 | 
			
		||||
因为action还通过httpbody获取了一个_authUserTicket参数,所以UserTicket需要加[FromHeader]特性。   
 | 
			
		||||
 | 
			
		||||
### 6、自定义ClaimTicket配置   
 | 
			
		||||
通过ClaimTicketOptions对象完成配置。完成配置的途径有两个。  
 | 
			
		||||
> 1、在插件配置中优先注入自己的ClaimTicketOptions对象。
 | 
			
		||||
> ~~~c#
 | 
			
		||||
> public class ServicePlugin:IServicePlugin
 | 
			
		||||
> {
 | 
			
		||||
>     IServiceCollection IServicePlugin.AddServices(IServiceCollection services,IConfiguration configuration) {
 | 
			
		||||
>         //注入使用ClaimTicket的控制器
 | 
			
		||||
>         services.AddPluginsController(this.GetType().Assembly);
 | 
			
		||||
> 
 | 
			
		||||
>         //优先添加自己的服务配置
 | 
			
		||||
>         services.AddSingleton(new ClaimTicketOptions());
 | 
			
		||||
> 
 | 
			
		||||
>         //添加ClaimTicket服务支持
 | 
			
		||||
>         services.AddClaimTicket();
 | 
			
		||||
>         return services;
 | 
			
		||||
>     }
 | 
			
		||||
> }
 | 
			
		||||
> ~~~
 | 
			
		||||
> 2、在插件配置中优先注入自己的ClaimTicketOptions对象。
 | 
			
		||||
> ~~~c#
 | 
			
		||||
> public class ServicePlugin:IServicePlugin
 | 
			
		||||
> {
 | 
			
		||||
>     IServiceCollection IServicePlugin.AddServices(IServiceCollection services,IConfiguration configuration) {
 | 
			
		||||
>         //注入使用ClaimTicket的控制器
 | 
			
		||||
>         services.AddPluginsController(this.GetType().Assembly);
 | 
			
		||||
> 
 | 
			
		||||
>         //优先添加自己的服务配置
 | 
			
		||||
>         //services.AddSingleton(new ClaimTicketOptions());
 | 
			
		||||
> 
 | 
			
		||||
>         //添加ClaimTicket服务支持
 | 
			
		||||
>         services.AddClaimTicket(optionsBuilder => {
 | 
			
		||||
>             //客户端通过_headCalimTick属性提交凭据
 | 
			
		||||
>             optionsBuilder.HttpHeaderKey = "_headCalimTick";
 | 
			
		||||
>         });
 | 
			
		||||
>         return services;
 | 
			
		||||
>     }
 | 
			
		||||
> }
 | 
			
		||||
> ~~~   
 | 
			
		||||
### 7、扩展ITicketBuilder  
 | 
			
		||||
插件可以自行扩展票据的生成方式,方法有两个,一个是继承TicketBuilder对象并重写方法,另一个就是自己实现ITicketBuilder接口。  
 | 
			
		||||
 | 
			
		||||
~~~c#
 | 
			
		||||
/// <summary>
 | 
			
		||||
/// 自定义票据生成方式
 | 
			
		||||
/// </summary>
 | 
			
		||||
public class MyTicketBuilder:TicketBuilder, ITicketBuilder
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 使用票据参数构造生成器
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <param name="options">生成参数</param>
 | 
			
		||||
    public MyTicketBuilder(ClaimTicketOptions options) : base(options) { }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc/>
 | 
			
		||||
    public override string? GetTicket(UserTicket userTicket) {
 | 
			
		||||
        //实现自己的票据生成方法
 | 
			
		||||
            
 | 
			
		||||
        //或使用基类提供的方法
 | 
			
		||||
        return base.GetTicket(userTicket);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <inheritdoc/>
 | 
			
		||||
    public override UserTicket? GetUser(string ticket) {
 | 
			
		||||
        //根据票据获取用户声明返回用户信息
 | 
			
		||||
 | 
			
		||||
        //或使用基类提供的方法
 | 
			
		||||
        return base.GetUser(ticket);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
~~~
 | 
			
		||||
然后在调用AddClaimTicket之前注入自己的ITicketBuilder
 | 
			
		||||
~~~c#
 | 
			
		||||
public class ServicePlugin:IServicePlugin
 | 
			
		||||
{
 | 
			
		||||
    IServiceCollection IServicePlugin.AddServices(IServiceCollection services,IConfiguration configuration) {
 | 
			
		||||
        //注入使用ClaimTicket的控制器
 | 
			
		||||
        services.AddPluginsController(this.GetType().Assembly);
 | 
			
		||||
 | 
			
		||||
        //优先添加自己的服务配置
 | 
			
		||||
        //services.AddSingleton(new ClaimTicketOptions());
 | 
			
		||||
 | 
			
		||||
        //注入扩展MyTicketBuilder
 | 
			
		||||
        services.TryAddSingleton<ITicketBuilder,MyTicketBuilder>();
 | 
			
		||||
 | 
			
		||||
        //添加ClaimTicket服务支持
 | 
			
		||||
        services.AddClaimTicket(optionsBuilder => {
 | 
			
		||||
            //客户端通过_headCalimTick属性提交凭据
 | 
			
		||||
            optionsBuilder.HttpHeaderKey = "_headCalimTick";
 | 
			
		||||
        });
 | 
			
		||||
        return services;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
~~~
 | 
			
		||||
							
								
								
									
										43
									
								
								Falcon.SugarApi/ClaimTicket/ServiceCollectionExtend.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								Falcon.SugarApi/ClaimTicket/ServiceCollectionExtend.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,43 @@
 | 
			
		||||
using Falcon.SugarApi.Encryption;
 | 
			
		||||
using Falcon.SugarApi.JsonSerialize;
 | 
			
		||||
using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
using Microsoft.Extensions.DependencyInjection.Extensions;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Falcon.SugarApi.ClaimTicket
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 服务扩展
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public static class ServiceCollectionExtend
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 增加客户凭据支持
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="services">服务集合</param>
 | 
			
		||||
        /// <param name="OptionBuilder">配置创建</param>
 | 
			
		||||
        /// <returns>服务集合</returns>
 | 
			
		||||
        public static IServiceCollection AddClaimTicket(this IServiceCollection services,Action<ClaimTicketOptions>? OptionBuilder = null) {
 | 
			
		||||
            services.TryAddSingleton<ClaimTicketOptions>(p => {
 | 
			
		||||
                var en = p.GetRequiredService<IEncryption>();
 | 
			
		||||
                var ser = p.GetRequiredService<IJsonSerialize>();
 | 
			
		||||
                var option = new ClaimTicketOptions {
 | 
			
		||||
                    Encryption = en,JsonSerialize = ser,
 | 
			
		||||
                };
 | 
			
		||||
                OptionBuilder?.Invoke(option);
 | 
			
		||||
                return option;
 | 
			
		||||
            });
 | 
			
		||||
            services.TryAddSingleton<IEncryption,AESProvider>();
 | 
			
		||||
            services.TryAddSingleton<IJsonSerialize,JsonSerialize.JsonSerialize>();
 | 
			
		||||
            services.TryAddSingleton<ITicketBuilder,TicketBuilder>();
 | 
			
		||||
            services.AddControllers(op => {
 | 
			
		||||
                op.ModelBinderProviders.Insert(0,new ClaimTicketModelBindingProvider());
 | 
			
		||||
            });
 | 
			
		||||
            return services;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										63
									
								
								Falcon.SugarApi/ClaimTicket/TicketBuilder.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								Falcon.SugarApi/ClaimTicket/TicketBuilder.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,63 @@
 | 
			
		||||
using Falcon.SugarApi.Encryption;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Security.Claims;
 | 
			
		||||
 | 
			
		||||
namespace Falcon.SugarApi.ClaimTicket
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 票据生成器
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class TicketBuilder:ITicketBuilder
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 构造票据生成器
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="options">加密配置</param>
 | 
			
		||||
        public TicketBuilder(ClaimTicketOptions options) {
 | 
			
		||||
            this.Encryption = options.Encryption;
 | 
			
		||||
            this.Serialize = options.JsonSerialize;
 | 
			
		||||
            this.Options = options;
 | 
			
		||||
        }
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 加密模块
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public IEncryption Encryption { get; }
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 序列化模块
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public ISerialize Serialize { get; }
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 票据生成配置
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public ClaimTicketOptions Options { get; }
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc/>
 | 
			
		||||
        public virtual UserTicket? GetUser(string ticket) {
 | 
			
		||||
            var str = this.Encryption.Decrypt(this.Options.EncryptionKey,ticket);
 | 
			
		||||
            if(str.IsNullOrEmpty()) {
 | 
			
		||||
                return new UserTicket();
 | 
			
		||||
            }
 | 
			
		||||
            var list = this.Serialize.Deserialize<List<ClaimKeyValue>>(str);
 | 
			
		||||
            if(list == null) {
 | 
			
		||||
                return new UserTicket();
 | 
			
		||||
            }
 | 
			
		||||
            return new UserTicket(list.Select(a => new Claim(a.Key,a.Value)));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <inheritdoc/>
 | 
			
		||||
        public virtual string? GetTicket(UserTicket userTicket) {
 | 
			
		||||
            if(userTicket == null) {
 | 
			
		||||
                return string.Empty;
 | 
			
		||||
            }
 | 
			
		||||
            var claims = userTicket.Claims;
 | 
			
		||||
            if(claims == null || claims.Count == 0) {
 | 
			
		||||
                return string.Empty;
 | 
			
		||||
            }
 | 
			
		||||
            var list = claims.Select(a => new ClaimKeyValue { Key = a.Type,Value = a.Value });
 | 
			
		||||
            var str = this.Serialize.Serialize(list);
 | 
			
		||||
            var sstr = this.Encryption.Encrypt(this.Options.EncryptionKey,str);
 | 
			
		||||
            return sstr;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										77
									
								
								Falcon.SugarApi/ClaimTicket/UserTicket.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								Falcon.SugarApi/ClaimTicket/UserTicket.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,77 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Security.Claims;
 | 
			
		||||
 | 
			
		||||
namespace Falcon.SugarApi.ClaimTicket
 | 
			
		||||
{
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// 用户票据
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class UserTicket
 | 
			
		||||
    {
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 存储用户声明
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public List<Claim> Claims { get; set; } = new List<Claim>();
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 构造空白票据
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public UserTicket() { }
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 通过声明列表构造票据
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="claims">声称</param>
 | 
			
		||||
        public UserTicket(IEnumerable<Claim> claims) {
 | 
			
		||||
            this.Claims = claims.ToList();
 | 
			
		||||
        }
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 通过声明列表构造票据
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="claims">声称</param>
 | 
			
		||||
        public UserTicket(params Claim[] claims) : this(claims.ToList()) { }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 增加用户声明
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="claims"></param>
 | 
			
		||||
        public void AddClaims(params Claim[] claims) {
 | 
			
		||||
            if(claims.Length == 0) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            foreach(var c in claims) {
 | 
			
		||||
                var f = this.Claims.Find(a => a.Type == c.Type);
 | 
			
		||||
                if(f != null) {
 | 
			
		||||
                    this.Claims.Remove(f);
 | 
			
		||||
                }
 | 
			
		||||
                this.Claims.Add(c);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 为用户添加键和值
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="key">键</param>
 | 
			
		||||
        /// <param name="val">值</param>
 | 
			
		||||
        public void AddClaim(string key,string val) {
 | 
			
		||||
            if(key.IsNullOrEmpty()) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            if(val.IsNullOrEmpty()) {
 | 
			
		||||
                var c = this.Claims.Find(a => a.Type == key);
 | 
			
		||||
                if(c != null) {
 | 
			
		||||
                    this.Claims.Remove(c);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            this.AddClaims(new Claim(key,val));
 | 
			
		||||
        }
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// 获取用户声明的值
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="key">声明键</param>
 | 
			
		||||
        /// <returns>值</returns>
 | 
			
		||||
        public string? GetValue(string key) {
 | 
			
		||||
            var c = this.Claims.Find(a => a.Type == key);
 | 
			
		||||
            return c == null ? string.Empty : c.Value;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user