飞出JWT,新增FalconClaim用于api的Token认证
This commit is contained in:
parent
ce77072812
commit
2488b15532
|
@ -1,51 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Falcon.SugarApi.JWT;
|
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
|
|
||||||
namespace Falcon.SugarApi.Test
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// JwtTokenBuilderTest
|
|
||||||
/// </summary>
|
|
||||||
[TestClass]
|
|
||||||
public class JwtTokenBuilderTest
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Token获取测试
|
|
||||||
/// </summary>
|
|
||||||
[TestMethod]
|
|
||||||
public void GetTokenTest() {
|
|
||||||
var loginTime = DateTime.Now;
|
|
||||||
var playload = new LoginUserInfo {
|
|
||||||
UserName = "abdc",
|
|
||||||
LoginTime = loginTime,
|
|
||||||
Roles = new List<string> { "admin", "user" },
|
|
||||||
};
|
|
||||||
if (new JwtTokenBuilder().TryGetToken(playload, out var token, out var exception)) {
|
|
||||||
Console.WriteLine("token:{0}", token);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Console.WriteLine(exception.ToString());
|
|
||||||
Assert.Fail("获取token失败");
|
|
||||||
}
|
|
||||||
Assert.IsNotNull(token);
|
|
||||||
if (new JwtTokenBuilder().TryGetPlayload(token, out var pl, out var exception1)) {
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Console.WriteLine(exception1.ToString());
|
|
||||||
Assert.Fail("获取Playload失败");
|
|
||||||
}
|
|
||||||
Assert.IsNotNull(pl);
|
|
||||||
Assert.AreEqual(playload.UserName, pl.UserName);
|
|
||||||
Assert.IsTrue(pl.Roles != null);
|
|
||||||
Assert.IsTrue(pl.Roles.Count == 2);
|
|
||||||
Assert.IsTrue(pl.Roles.Any(m => m == "admin"));
|
|
||||||
Assert.IsTrue(pl.Roles.Any(m => m == "user"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
44
Falcon.SugarApi/FalconClaim/AddFalconClaimHeaderFilter.cs
Normal file
44
Falcon.SugarApi/FalconClaim/AddFalconClaimHeaderFilter.cs
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
using Microsoft.AspNetCore.Mvc.Authorization;
|
||||||
|
using Microsoft.OpenApi.Any;
|
||||||
|
using Microsoft.OpenApi.Models;
|
||||||
|
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Falcon.SugarApi.FalconClaim
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 为swagger openapi接口增加验证选项
|
||||||
|
/// </summary>
|
||||||
|
public class AddFalconClaimHeaderFilter:IOperationFilter
|
||||||
|
{
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void Apply(OpenApiOperation operation,OperationFilterContext context) {
|
||||||
|
var filterPipeline = context.ApiDescription.ActionDescriptor.FilterDescriptors;
|
||||||
|
//var isAuthorized = filterPipeline.Select(filterInfo => filterInfo.Filter)
|
||||||
|
// .Any(filter => filter is FalconClaimAuthorizeAttribute);
|
||||||
|
|
||||||
|
|
||||||
|
var metedata = context.ApiDescription.ActionDescriptor.EndpointMetadata;
|
||||||
|
var isAuthorized = metedata.Any(m => m is FalconClaimAuthorizeAttribute);
|
||||||
|
var allowAnonymous = filterPipeline.Select(filterInfo => filterInfo.Filter)
|
||||||
|
.Any(filter => filter is IAllowAnonymousFilter);
|
||||||
|
|
||||||
|
if(isAuthorized && !allowAnonymous) {
|
||||||
|
operation.Parameters = operation.Parameters ?? new List<OpenApiParameter>();
|
||||||
|
|
||||||
|
operation.Parameters.Add(new OpenApiParameter {
|
||||||
|
Name = FalconClaimOption.FalconAuthenticationKey,
|
||||||
|
In = ParameterLocation.Header,
|
||||||
|
Description = FalconClaimOption.Description,
|
||||||
|
Required = true,
|
||||||
|
Schema = new OpenApiSchema {
|
||||||
|
Type = "string",
|
||||||
|
Default = new OpenApiString(FalconClaimOption.TokenPrefix),
|
||||||
|
},
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
56
Falcon.SugarApi/FalconClaim/AesTokenBuilder.cs
Normal file
56
Falcon.SugarApi/FalconClaim/AesTokenBuilder.cs
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
using Falcon.SugarApi.Encryption;
|
||||||
|
using Falcon.SugarApi.JsonSerialize;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
|
namespace Falcon.SugarApi.FalconClaim
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 利用AES生成token
|
||||||
|
/// </summary>
|
||||||
|
public class AesTokenBuilder:ITokenBuilter
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 构造基于AES算法的token生成器
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="aes">aes算法</param>
|
||||||
|
/// <param name="factory">json工厂</param>
|
||||||
|
public AesTokenBuilder(IAESEncryption aes,JsonSerializeFactory factory) {
|
||||||
|
Aes = aes;
|
||||||
|
this.Json = factory.CreateJsonSerialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IAESEncryption Aes { get; }
|
||||||
|
|
||||||
|
public IJsonSerialize Json { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public List<Claim>? GetClaims(string token) {
|
||||||
|
var str = this.Aes.Decrypt(FalconClaimOption.SecKey,token);
|
||||||
|
if(str.IsNullOrEmpty()) {
|
||||||
|
return new List<Claim>();
|
||||||
|
}
|
||||||
|
return this.Json.Deserialize<List<ClaimSerModel>>(str)
|
||||||
|
.Select(m => new Claim(m.Type,m.Value)).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public string? GetToken(List<Claim> claims) {
|
||||||
|
var obj = claims.Select(m => new ClaimSerModel(m.Type,m.Value));
|
||||||
|
return this.Aes.Encrypt(FalconClaimOption.SecKey,this.Json.Serialize(obj));
|
||||||
|
}
|
||||||
|
class ClaimSerModel
|
||||||
|
{
|
||||||
|
public ClaimSerModel(string type,string value) {
|
||||||
|
Type = type;
|
||||||
|
Value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Type { get; set; }
|
||||||
|
public string Value { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
23
Falcon.SugarApi/FalconClaim/ClaimsIdentityExtend.cs
Normal file
23
Falcon.SugarApi/FalconClaim/ClaimsIdentityExtend.cs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
|
namespace Falcon.SugarApi.FalconClaim
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 身份扩展
|
||||||
|
/// </summary>
|
||||||
|
public static class ClaimsIdentityExtend
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 象身份中增加声明
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="cid">身份</param>
|
||||||
|
/// <param name="ClaimTypes">声明类型</param>
|
||||||
|
/// <param name="value">声明值</param>
|
||||||
|
/// <returns>身份</returns>
|
||||||
|
public static ClaimsIdentity AddClaim(this ClaimsIdentity cid,string ClaimTypes,string value) {
|
||||||
|
cid.AddClaim(new Claim(ClaimTypes,value));
|
||||||
|
return cid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
108
Falcon.SugarApi/FalconClaim/FalconAuthenticationHandler.cs
Normal file
108
Falcon.SugarApi/FalconClaim/FalconAuthenticationHandler.cs
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
using Microsoft.AspNetCore.Authentication;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Net;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Falcon.SugarApi.FalconClaim
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 自定义验证方式
|
||||||
|
/// </summary>
|
||||||
|
public class FalconAuthenticationHandler:IAuthenticationHandler
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 构造自定义身份验证方式
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tokenBuilter">token工具</param>
|
||||||
|
public FalconAuthenticationHandler(ITokenBuilter tokenBuilter) {
|
||||||
|
this.Scheme = null;
|
||||||
|
this.Context = null;
|
||||||
|
TokenBuilter = tokenBuilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 验证计划,模式
|
||||||
|
/// </summary>
|
||||||
|
public AuthenticationScheme? Scheme { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// HttpContext 上下文
|
||||||
|
/// </summary>
|
||||||
|
public HttpContext? Context { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public Task<AuthenticateResult> AuthenticateAsync() {
|
||||||
|
if(!this.Context.Request.Headers.TryGetValue(FalconClaimOption.FalconAuthenticationKey,out var val)) {
|
||||||
|
return UnLoginResultTask;
|
||||||
|
}
|
||||||
|
var token = val.ToString();
|
||||||
|
if(token.IsNullOrEmpty()) {
|
||||||
|
return UnLoginResultTask;
|
||||||
|
}
|
||||||
|
if(FalconClaimOption.TokenPrefix.IsNotNullOrEmpty() && !token.StartsWith(FalconClaimOption.TokenPrefix)) {
|
||||||
|
return UnLoginResultTask;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
var ticket = GetTicket(token);
|
||||||
|
if(ticket == null) {
|
||||||
|
return UnLoginResultTask;
|
||||||
|
}
|
||||||
|
return Task.FromResult(AuthenticateResult.Success(ticket));
|
||||||
|
} catch(Exception) {
|
||||||
|
return UnLoginResultTask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public Task ChallengeAsync(AuthenticationProperties? properties) {
|
||||||
|
this.Context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public Task ForbidAsync(AuthenticationProperties? properties) {
|
||||||
|
this.Context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public Task InitializeAsync(AuthenticationScheme scheme,HttpContext context) {
|
||||||
|
this.Scheme = scheme; this.Context = context;
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据登录token获取票据
|
||||||
|
/// </summary>
|
||||||
|
private AuthenticationTicket? GetTicket(string token) {
|
||||||
|
token.ThrowNullExceptionWhenNull();
|
||||||
|
List<Claim>? claims = null;
|
||||||
|
try {
|
||||||
|
claims = this.TokenBuilter.GetClaims(token);
|
||||||
|
} catch(Exception) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if(claims == null || claims.Count == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
var cid = new ClaimsIdentity(FalconClaimOption.SchemeName);
|
||||||
|
cid.AddClaims(claims);
|
||||||
|
var principal = new ClaimsPrincipal(cid);
|
||||||
|
return new AuthenticationTicket(principal,this.Scheme.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 验证失败任务
|
||||||
|
/// </summary>
|
||||||
|
//public static Task<AuthenticateResult> UnLoginResultTask => throw new ApiDefinistions.ApiException("未登录");
|
||||||
|
public static Task<AuthenticateResult> UnLoginResultTask => Task.FromResult(AuthenticateResult.Fail("未登录"));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Token工具
|
||||||
|
/// </summary>
|
||||||
|
public ITokenBuilter TokenBuilter { get; }
|
||||||
|
}
|
||||||
|
}
|
27
Falcon.SugarApi/FalconClaim/FalconClaimAuthorizeAttribute.cs
Normal file
27
Falcon.SugarApi/FalconClaim/FalconClaimAuthorizeAttribute.cs
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
|
||||||
|
namespace Falcon.SugarApi.FalconClaim
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 根据角色验证
|
||||||
|
/// </summary>
|
||||||
|
public class FalconClaimAuthorizeAttribute:AuthorizeAttribute
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 通过提供的角色进行验证
|
||||||
|
/// </summary>
|
||||||
|
public FalconClaimAuthorizeAttribute() {
|
||||||
|
base.AuthenticationSchemes = FalconClaimOption.SchemeName;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 通过提供的角色进行验证
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="roles">,号分割的角色列表</param>
|
||||||
|
public FalconClaimAuthorizeAttribute(string roles) {
|
||||||
|
base.AuthenticationSchemes = FalconClaimOption.SchemeName;
|
||||||
|
base.Roles = roles;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
40
Falcon.SugarApi/FalconClaim/FalconClaimOption.cs
Normal file
40
Falcon.SugarApi/FalconClaim/FalconClaimOption.cs
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Falcon.SugarApi.FalconClaim
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// FalconClaim验证选项
|
||||||
|
/// </summary>
|
||||||
|
public class FalconClaimOption
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 自定义验证方式名
|
||||||
|
/// </summary>
|
||||||
|
public static string SchemeName { get; set; } = "FalconClaimSchemeName";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用于提供验证token的键
|
||||||
|
/// </summary>
|
||||||
|
public static string FalconAuthenticationKey { get; set; } = "Falcon_WWW_Authenticate";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用于加密的key
|
||||||
|
/// </summary>
|
||||||
|
public static string SecKey { get; set; } = "E9319792CB7249AD8E432000E9F2FE7A";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 验证头说明
|
||||||
|
/// </summary>
|
||||||
|
public static string Description { get; set; } = "FalconClaim验证的Token。";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 请求Token前缀
|
||||||
|
/// </summary>
|
||||||
|
public static string TokenPrefix { get; set; } = "";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 二次认证方法
|
||||||
|
/// </summary>
|
||||||
|
public List<IUserValidate> UserValidates { get; set; } = new List<IUserValidate>();
|
||||||
|
}
|
||||||
|
}
|
18
Falcon.SugarApi/FalconClaim/IApplicationBuilderExtend.cs
Normal file
18
Falcon.SugarApi/FalconClaim/IApplicationBuilderExtend.cs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
|
||||||
|
namespace Falcon.SugarApi.FalconClaim
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 扩展IApplicationBuilder
|
||||||
|
/// </summary>
|
||||||
|
public static class IApplicationBuilderExtend
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 使用认证UseAuthentication和授权UseAuthorization。需要加在在UseRouting后UseEndpoints前
|
||||||
|
/// </summary>
|
||||||
|
public static IApplicationBuilder UseFalconClaim(this IApplicationBuilder app) {
|
||||||
|
app.UseAuthentication().UseAuthorization();
|
||||||
|
return app;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
33
Falcon.SugarApi/FalconClaim/IServiceCollectionExtend.cs
Normal file
33
Falcon.SugarApi/FalconClaim/IServiceCollectionExtend.cs
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
using Falcon.SugarApi.Encryption;
|
||||||
|
using Falcon.SugarApi.JsonSerialize;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||||
|
using System;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
|
namespace Falcon.SugarApi.FalconClaim
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 扩展IServiceCollection
|
||||||
|
/// </summary>
|
||||||
|
public static class IServiceCollectionExtend
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 增加FalconCalom相关服务
|
||||||
|
/// </summary>
|
||||||
|
public static IServiceCollection AddFalconClaim(this IServiceCollection services,Action<FalconClaimOption>? optionBuilder = null) {
|
||||||
|
optionBuilder?.Invoke(new FalconClaimOption());
|
||||||
|
services.TryAddSingleton<JsonSerializeFactory>();
|
||||||
|
services.TryAddSingleton<ITokenBuilter,AesTokenBuilder>();
|
||||||
|
services.TryAddSingleton<AESConfig>();
|
||||||
|
services.TryAddSingleton<IAESEncryption,AESProvider>();
|
||||||
|
services.AddAuthentication(b => {
|
||||||
|
b.DefaultAuthenticateScheme = FalconClaimOption.SchemeName;
|
||||||
|
b.DefaultChallengeScheme = FalconClaimOption.SchemeName;
|
||||||
|
b.DefaultForbidScheme = FalconClaimOption.SchemeName;
|
||||||
|
b.AddScheme<FalconAuthenticationHandler>(FalconClaimOption.SchemeName,FalconClaimOption.SchemeName);
|
||||||
|
});
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
24
Falcon.SugarApi/FalconClaim/ITokenBuilter.cs
Normal file
24
Falcon.SugarApi/FalconClaim/ITokenBuilter.cs
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
|
namespace Falcon.SugarApi.FalconClaim
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 通过声明生成token
|
||||||
|
/// </summary>
|
||||||
|
public interface ITokenBuilter
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 根据声称组生成token
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="claims">一组声明</param>
|
||||||
|
/// <returns>token</returns>
|
||||||
|
string? GetToken(List<Claim> claims);
|
||||||
|
/// <summary>
|
||||||
|
/// 通过token获取声明组
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="token">token</param>
|
||||||
|
/// <returns>声明组</returns>
|
||||||
|
List<Claim>? GetClaims(string token);
|
||||||
|
}
|
||||||
|
}
|
16
Falcon.SugarApi/FalconClaim/IUserValidate.cs
Normal file
16
Falcon.SugarApi/FalconClaim/IUserValidate.cs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
|
namespace Falcon.SugarApi.FalconClaim
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 认证时候提供二次验证方法
|
||||||
|
/// </summary>
|
||||||
|
public interface IUserValidate
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 在认证时候提供二次认证的方法
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="identity">身份</param>
|
||||||
|
void UserLogin(ClaimsIdentity identity);
|
||||||
|
}
|
||||||
|
}
|
16
Falcon.SugarApi/FalconClaim/NameClaim.cs
Normal file
16
Falcon.SugarApi/FalconClaim/NameClaim.cs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
|
namespace Falcon.SugarApi.FalconClaim
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 名字声明
|
||||||
|
/// </summary>
|
||||||
|
public class NameClaim:Claim
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 提供名字实现名字声明
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">名字</param>
|
||||||
|
public NameClaim(string name) : base(ClaimTypes.Name,name) { }
|
||||||
|
}
|
||||||
|
}
|
7
Falcon.SugarApi/FalconClaim/Readme.md
Normal file
7
Falcon.SugarApi/FalconClaim/Readme.md
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
FalconClaim 使用说明:
|
||||||
|
|
||||||
|
|
||||||
|
1. 用户登录:模块提供了UserLoginModel和UserLoginResult类,分别负责提供登录凭据和登录结果,可以扩展使用,当然也可以使用自己的模型类。
|
||||||
|
> 1.通过UserLoginModel提供的凭据验证用户合法性。
|
||||||
|
> 2.通过ITokenBuilter.GetToken方法获取登录token。该方法需要一个Claim列表,该列表至少应包含一个name和role声明,表示登录的用户名和角色,也可以根据需要增加其他声明。
|
||||||
|
> 3.构造UserLoginResult对象返回token。
|
18
Falcon.SugarApi/FalconClaim/SidClaim.cs
Normal file
18
Falcon.SugarApi/FalconClaim/SidClaim.cs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
|
namespace Falcon.SugarApi.FalconClaim
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 安全标识声明
|
||||||
|
/// </summary>
|
||||||
|
public class SidClaim:Claim
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 提供名字实现名字声明
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sid">安全标识</param>
|
||||||
|
public SidClaim(string sid) : base(ClaimTypes.Sid,sid) { }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
51
Falcon.SugarApi/FalconClaim/SwaggerGenOptionsExtend.cs
Normal file
51
Falcon.SugarApi/FalconClaim/SwaggerGenOptionsExtend.cs
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.OpenApi.Models;
|
||||||
|
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Falcon.SugarApi.FalconClaim
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// SwaggerGenOptions扩展
|
||||||
|
/// </summary>
|
||||||
|
public static class SwaggerGenOptionsExtend
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 在swaggerUI中为有FalconClaimAuthorizeAttribute特性的Action增加token头
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="options">SwaggerGenOptions</param>
|
||||||
|
/// <returns>SwaggerGenOptions</returns>
|
||||||
|
public static SwaggerGenOptions AddHeaderForFalconClaim(this SwaggerGenOptions options) {
|
||||||
|
options.OperationFilter<AddFalconClaimHeaderFilter>();
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 在swaggerUI中为所有api请求增加token头
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="options">SwaggerGenOptions</param>
|
||||||
|
/// <returns>SwaggerGenOptions</returns>
|
||||||
|
public static SwaggerGenOptions AddHeaderForAllApi(this SwaggerGenOptions options) {
|
||||||
|
options.AddSecurityDefinition(FalconClaimOption.SchemeName,new OpenApiSecurityScheme {
|
||||||
|
Description = FalconClaimOption.Description,
|
||||||
|
Name = FalconClaimOption.FalconAuthenticationKey,
|
||||||
|
In = ParameterLocation.Header,
|
||||||
|
Type = SecuritySchemeType.ApiKey,
|
||||||
|
Scheme = FalconClaimOption.SchemeName,
|
||||||
|
});
|
||||||
|
options.AddSecurityRequirement(new OpenApiSecurityRequirement {
|
||||||
|
{
|
||||||
|
new OpenApiSecurityScheme
|
||||||
|
{
|
||||||
|
Reference = new OpenApiReference {
|
||||||
|
Type = ReferenceType.SecurityScheme,
|
||||||
|
Id =FalconClaimOption.SchemeName,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new List<string>()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
18
Falcon.SugarApi/FalconClaim/UserLoginModel.cs
Normal file
18
Falcon.SugarApi/FalconClaim/UserLoginModel.cs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
namespace Falcon.SugarApi.FalconClaim
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 用户登录凭据模板
|
||||||
|
/// <para>用于验证用户登录,可以实现自己的类进行验证</para>
|
||||||
|
/// </summary>
|
||||||
|
public class UserLoginModel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 用户名
|
||||||
|
/// </summary>
|
||||||
|
public string? UserName { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 密码
|
||||||
|
/// </summary>
|
||||||
|
public string? Password { get; set; }
|
||||||
|
}
|
||||||
|
}
|
44
Falcon.SugarApi/FalconClaim/UserLoginResult.cs
Normal file
44
Falcon.SugarApi/FalconClaim/UserLoginResult.cs
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Falcon.SugarApi.FalconClaim
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 用户登录凭据模板
|
||||||
|
/// <para>登录结果,Token作为票据返回。</para>
|
||||||
|
/// </summary>
|
||||||
|
public class UserLoginResult
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 登录结果。成功返回True,失败返回False
|
||||||
|
/// </summary>
|
||||||
|
public bool Success { get; set; } = false;
|
||||||
|
/// <summary>
|
||||||
|
/// 登录结果信息
|
||||||
|
/// </summary>
|
||||||
|
public string? Msg { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 登录票据Token
|
||||||
|
/// </summary>
|
||||||
|
public string? Token { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 登录时间。默认当前系统时间
|
||||||
|
/// </summary>
|
||||||
|
public DateTime? LoginTime { get; set; } = DateTime.Now;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取一条成功的登录信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="token">成功登录Token</param>
|
||||||
|
/// <returns>成功登录结果</returns>
|
||||||
|
public static UserLoginResult LoginSuccess(string token)
|
||||||
|
=> new UserLoginResult { Success = true,Token = token,Msg = "ok" };
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 登录失败。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="msg">失败原因</param>
|
||||||
|
/// <returns>失败的登录结果</returns>
|
||||||
|
public static UserLoginResult LoginFail(string? msg)
|
||||||
|
=> new UserLoginResult { Success = false,Msg = msg };
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,42 +0,0 @@
|
||||||
using Falcon.SugarApi.Encryption;
|
|
||||||
|
|
||||||
namespace Falcon.SugarApi.JWT
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 使用AES算法生成Token
|
|
||||||
/// </summary>
|
|
||||||
public class AESTokenbuilder : IJwtTokenBuilder
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// AES加密算法
|
|
||||||
/// </summary>
|
|
||||||
public IAESEncryption AES { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// jwt生成参数
|
|
||||||
/// </summary>
|
|
||||||
public JwtContext Jwt { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 构造AES的Token
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="config">AES参数</param>
|
|
||||||
/// <param name="jwt">jwt生成参数</param>
|
|
||||||
public AESTokenbuilder(AESConfig config, JwtContext jwt) {
|
|
||||||
Jwt = jwt;
|
|
||||||
AES = new AESProvider(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc>/
|
|
||||||
public LoginUserInfo GetPlayload(string token) {
|
|
||||||
token.ThrowNullExceptionWhenNull();
|
|
||||||
return this.AES.Decrypt<LoginUserInfo>(Jwt.SecKey, token);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc>/
|
|
||||||
public string GetToken(LoginUserInfo playload) {
|
|
||||||
playload.ThrowNullExceptionWhenNull();
|
|
||||||
return this.AES.Encrypt(Jwt.SecKey, playload);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,73 +0,0 @@
|
||||||
using Microsoft.AspNetCore.Mvc.Authorization;
|
|
||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net;
|
|
||||||
|
|
||||||
namespace Falcon.SugarApi.JWT
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 验证
|
|
||||||
/// </summary>
|
|
||||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
|
|
||||||
public class ApiAuthorizationAttribute : Attribute, IAuthorizationFilter
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 用户需要具有的角色
|
|
||||||
/// </summary>
|
|
||||||
public string[] Roles { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 只需要登录即可通过验证
|
|
||||||
/// </summary>
|
|
||||||
public ApiAuthorizationAttribute() {
|
|
||||||
this.Roles = new string[] { };
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// 需要登录并且具有一定的角色
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="roles">角色组</param>
|
|
||||||
public ApiAuthorizationAttribute(params string[] roles) {
|
|
||||||
this.Roles = roles;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
public void OnAuthorization(AuthorizationFilterContext context) {
|
|
||||||
if (context.Filters.Any(f => f is IAllowAnonymousFilter)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var option = context.HttpContext.RequestServices.GetRequiredService<JwtContext>();
|
|
||||||
var key = option?.AuthHeaderKey;
|
|
||||||
key.ThrowNullExceptionWhenNull();
|
|
||||||
var token = context.HttpContext.Request.Headers[key].ToString();
|
|
||||||
if (token.IsNullOrEmpty()) {
|
|
||||||
Unauthorized(context);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var jwt = option?.JwtTokenBuilder;
|
|
||||||
jwt.ThrowNullExceptionWhenNull();
|
|
||||||
var user = jwt.GetPlayload(token);
|
|
||||||
var userLogin = option?.UserLogin;
|
|
||||||
if (userLogin != null && !userLogin.CheckUserLogin(user)) {
|
|
||||||
Unauthorized(context);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (this.Roles != null && this.Roles.Length > 0 && !userLogin.UserInRoles(user, this.Roles)) {
|
|
||||||
Unauthorized(context);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 返回授权失败
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="context">上下文</param>
|
|
||||||
private static void Unauthorized(AuthorizationFilterContext context) {
|
|
||||||
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
namespace Falcon.SugarApi.JWT
|
|
||||||
{
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// jwt token 生成器
|
|
||||||
/// </summary>
|
|
||||||
public interface IJwtTokenBuilder
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 获取Token负载
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="token">登录Token</param>
|
|
||||||
/// <returns>负载信息</returns>
|
|
||||||
LoginUserInfo GetPlayload(string token);
|
|
||||||
/// <summary>
|
|
||||||
/// 获取Token
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="playload">负载</param>
|
|
||||||
/// <returns>Token对象</returns>
|
|
||||||
string GetToken(LoginUserInfo playload);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
using Falcon.SugarApi.Encryption;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Falcon.SugarApi.JWT
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 服务扩展
|
|
||||||
/// </summary>
|
|
||||||
public static class IServiceCollectionExtend
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 注册Falcon.SqlSugar.JWT
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="services">服务集合</param>
|
|
||||||
/// <returns>服务集合</returns>
|
|
||||||
public static IServiceCollection AddFalconJWT(this IServiceCollection services)
|
|
||||||
=> services.AddFalconJWT(null);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 注册Falcon.SqlSugar.JWT.JwtContext,并配置相关参数
|
|
||||||
/// <para>消费端通过JwtContext注入</para>
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="services">服务集合</param>
|
|
||||||
/// <param name="OptionBuilder">参数创建器</param>
|
|
||||||
/// <returns>服务集合</returns>
|
|
||||||
public static IServiceCollection AddFalconJWT(this IServiceCollection services, Action<JwtContext>? OptionBuilder) {
|
|
||||||
services.AddSingleton<JwtContext>(sp => {
|
|
||||||
var option = new JwtContext();
|
|
||||||
var jtb = sp.GetService<IJwtTokenBuilder>();
|
|
||||||
if (jtb == null) {
|
|
||||||
var aesc = sp.GetService<AESConfig>() ?? new AESConfig();
|
|
||||||
jtb = new AESTokenbuilder(aesc, option);
|
|
||||||
}
|
|
||||||
option.JwtTokenBuilder = jtb;
|
|
||||||
|
|
||||||
var ulj = sp.GetService<IUserLogin>();
|
|
||||||
if (ulj != null) {
|
|
||||||
option.UserLogin = ulj;
|
|
||||||
}
|
|
||||||
|
|
||||||
OptionBuilder?.Invoke(option);
|
|
||||||
|
|
||||||
if (option.UserLogin == null) {
|
|
||||||
throw new Exception("必须为JwtOptions提供UserLogin属性!");
|
|
||||||
}
|
|
||||||
if (option.JwtTokenBuilder == null) {
|
|
||||||
throw new Exception("必须为JwtOptions提供JwtTokenBuilder属性!");
|
|
||||||
}
|
|
||||||
return option;
|
|
||||||
});
|
|
||||||
return services;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Falcon.SugarApi.JWT
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 用户登录验证接口
|
|
||||||
/// </summary>
|
|
||||||
public interface IUserLogin
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 登录是否成功
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="login">登录凭据</param>
|
|
||||||
/// <returns>成功返回用户信息,否则返回null</returns>
|
|
||||||
LoginUserInfo? Login(LoginDto login);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 用户登出
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="userInfo">用户名</param>
|
|
||||||
/// <returns>True成功,False失败</returns>
|
|
||||||
bool LogOut(LoginUserInfo userInfo);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 登录用户验证。检查客户端提供的已登录用户是否仍然处于登录中。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="userInfo">登录凭据</param>
|
|
||||||
/// <returns>登录中返回True,否则返回False</returns>
|
|
||||||
bool CheckUserLogin(LoginUserInfo userInfo);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 用户是否具有某个角色
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="userInfo">用户信息</param>
|
|
||||||
/// <param name="roles">需要具有的角色组</param>
|
|
||||||
/// <returns>True具有,False不具有</returns>
|
|
||||||
bool UserInRoles(LoginUserInfo userInfo, params string[] roles);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
namespace Falcon.SugarApi.JWT
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// JWT认证上下文
|
|
||||||
/// </summary>
|
|
||||||
public class JwtContext
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 验证头的键值
|
|
||||||
/// </summary>
|
|
||||||
public string AuthHeaderKey { get; set; } = "auth";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 用户Token加密的秘钥
|
|
||||||
/// </summary>
|
|
||||||
public string SecKey { get; set; } = "fefafwefwf464664f64e64f63";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// jwtToken生成器
|
|
||||||
/// </summary>
|
|
||||||
public IJwtTokenBuilder? JwtTokenBuilder { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 用户登录管理
|
|
||||||
/// </summary>
|
|
||||||
public IUserLogin? UserLogin { get; set; }
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,64 +0,0 @@
|
||||||
using JWT;
|
|
||||||
using JWT.Algorithms;
|
|
||||||
using JWT.Serializers;
|
|
||||||
using Microsoft.AspNetCore.Server.IIS.Core;
|
|
||||||
using System;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Falcon.SugarApi.JWT
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// jwt token 生成器
|
|
||||||
/// </summary>
|
|
||||||
public class JwtTokenBuilder : IJwtTokenBuilder
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 使用默认配置实例化
|
|
||||||
/// </summary>
|
|
||||||
public JwtTokenBuilder() : this(new JwtContext()) { }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 实例化
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="options">JWT认证配置</param>
|
|
||||||
public JwtTokenBuilder(JwtContext options) {
|
|
||||||
Options = options;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// JWT认证配置
|
|
||||||
/// </summary>
|
|
||||||
public JwtContext Options { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取Token
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="playload">负载</param>
|
|
||||||
/// <returns>Token对象</returns>
|
|
||||||
public string GetToken(LoginUserInfo playload) {
|
|
||||||
playload = playload ?? throw new ArgumentNullException(nameof(playload));
|
|
||||||
var key = Encoding.UTF8.GetBytes(this.Options.SecKey);
|
|
||||||
var algorithm = new HMACSHA256Algorithm();
|
|
||||||
var serializer = new JsonNetSerializer();
|
|
||||||
var urlEncoder = new JwtBase64UrlEncoder();
|
|
||||||
var encoder = new JwtEncoder(algorithm, serializer, urlEncoder);
|
|
||||||
return encoder.Encode(playload, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取Token负载
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="token">登录Token</param>
|
|
||||||
/// <returns>负载信息</returns>
|
|
||||||
public LoginUserInfo GetPlayload(string token) {
|
|
||||||
var key = Encoding.UTF8.GetBytes(this.Options.SecKey);
|
|
||||||
var serializer = new JsonNetSerializer();
|
|
||||||
var dtProvider = new UtcDateTimeProvider();
|
|
||||||
var validator = new JwtValidator(serializer, dtProvider);
|
|
||||||
var urlEncoder = new JwtBase64UrlEncoder();
|
|
||||||
var algorithm = new HMACSHA256Algorithm();
|
|
||||||
var decoder = new JwtDecoder(serializer, validator, urlEncoder, algorithm);
|
|
||||||
return decoder.DecodeToObject<LoginUserInfo>(token, key, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,52 +0,0 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Falcon.SugarApi.JWT
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// JwtTokenBuilder扩展
|
|
||||||
/// </summary>
|
|
||||||
public static class JwtTokenBuilderExtend
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 尝试获取Token
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="builder">生成器</param>
|
|
||||||
/// <param name="userInfo">用户信息</param>
|
|
||||||
/// <param name="token">生成的token</param>
|
|
||||||
/// <param name="exception">失败异常</param>
|
|
||||||
/// <returns>成功True,失败False</returns>
|
|
||||||
public static bool TryGetToken(this JwtTokenBuilder builder, LoginUserInfo userInfo, out string? token, out Exception? exception) {
|
|
||||||
try {
|
|
||||||
token = builder.GetToken(userInfo);
|
|
||||||
exception = null;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch (Exception ex) {
|
|
||||||
token = null;
|
|
||||||
exception = ex;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 尝试获取用户信息
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="builder">jwt创建器</param>
|
|
||||||
/// <param name="token">token</param>
|
|
||||||
/// <param name="userInfo">用户信息</param>
|
|
||||||
/// <param name="exception">异常</param>
|
|
||||||
/// <returns>True成功,False失败</returns>
|
|
||||||
public static bool TryGetPlayload(this JwtTokenBuilder builder, string token, out LoginUserInfo? userInfo, out Exception? exception) {
|
|
||||||
try {
|
|
||||||
userInfo = builder.GetPlayload(token);
|
|
||||||
exception = null;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch (Exception ex) {
|
|
||||||
userInfo = null;
|
|
||||||
exception = ex;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
namespace Falcon.SugarApi.JWT
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 登录信息
|
|
||||||
/// </summary>
|
|
||||||
public class LoginDto
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 用户名
|
|
||||||
/// </summary>
|
|
||||||
public string UserName { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// 密码
|
|
||||||
/// </summary>
|
|
||||||
public string Password { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Falcon.SugarApi.JWT
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// JWT载荷信息
|
|
||||||
/// </summary>
|
|
||||||
public class LoginUserInfo
|
|
||||||
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 登录用户名
|
|
||||||
/// </summary>
|
|
||||||
public string? UserName { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// 用户角色
|
|
||||||
/// </summary>
|
|
||||||
public List<string> Roles { get; set; } = new List<string>();
|
|
||||||
/// <summary>
|
|
||||||
/// 其他扩展用户信息
|
|
||||||
/// </summary>
|
|
||||||
public Dictionary<string, object> UserInfoExtend { get; set; } = new Dictionary<string, object>();
|
|
||||||
/// <summary>
|
|
||||||
/// 登录时间
|
|
||||||
/// </summary>
|
|
||||||
public DateTime? LoginTime { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
namespace Falcon.SugarApi.JWT
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 登录凭据
|
|
||||||
/// </summary>
|
|
||||||
public class TokenDto
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 登录结果
|
|
||||||
/// </summary>
|
|
||||||
public bool Success { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// 信息
|
|
||||||
/// </summary>
|
|
||||||
public string Message { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// 凭据
|
|
||||||
/// </summary>
|
|
||||||
public string Token { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
初始化过程:
|
|
||||||
1. 初始化相关表:
|
|
||||||
2. 初始化用户系统:检查是否存在用户,如果没有用户插入默认管理员用户,后期可以删除。
|
|
||||||
2. 初始化角色系统:
|
|
||||||
> 1. 检查系统所有控制器,查询是否标注ApiExplorerSettings特性,如果标注查询是否定义GroupName,不为空则列为角色之一。
|
|
||||||
> 2. 检查角色表,如果发现缺少某角色则插入。检查是否存在超管角色,如果不存在则插入
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user