添加授权鉴权模块

This commit is contained in:
橙子
2023-01-19 15:35:50 +08:00
parent fc74a000a6
commit f88655e214
33 changed files with 496 additions and 46 deletions

View File

@@ -47,9 +47,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.Office.Excel",
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.WeChatPay", "src\module\Yi.Framework.WeChatPay\Yi.Framework.WeChatPay.csproj", "{588D0DA9-303A-4FF0-A2D1-83037E2B269F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yi.Framework.Data", "Yi.Framework.Data\Yi.Framework.Data.csproj", "{DEE07142-32CE-4B5F-A5A3-452064EBF4A2}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.Data", "src\framework\Yi.Framework.Data\Yi.Framework.Data.csproj", "{DEE07142-32CE-4B5F-A5A3-452064EBF4A2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yi.Framework.Authentication.JwtBearer", "src\framework\Yi.Framework.Authentication.JwtBearer\Yi.Framework.Authentication.JwtBearer.csproj", "{D40C583D-58BE-422D-9A57-94DECB751EB4}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.Auth.JwtBearer", "src\framework\Yi.Framework.Auth.JwtBearer\Yi.Framework.Auth.JwtBearer.csproj", "{D40C583D-58BE-422D-9A57-94DECB751EB4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution

View File

@@ -0,0 +1,100 @@
using JWT;
using JWT.Algorithms;
using JWT.Builder;
using JWT.Exceptions;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Auth.JwtBearer.Authentication.Options;
using Yi.Framework.Core.Helper;
namespace Yi.Framework.Auth.JwtBearer.Authentication
{
public class JwtTokenManager
{
private JwtTokenOptions _jwtTokenOptions;
public JwtTokenManager(IOptions<JwtTokenOptions> options)
{
_jwtTokenOptions = options.Value;
}
public string CreateToken(Dictionary<string, object>? claimDic)
{
var token = JwtBuilder.Create()
.WithAlgorithm(new RS256Algorithm(RSAFileHelper.GetKey(), RSAFileHelper.GetKey()))
.AddClaim(ClaimName.Issuer, _jwtTokenOptions.Issuer)
.AddClaim(ClaimName.Audience, _jwtTokenOptions.Audience)
.AddClaim(ClaimName.Subject, _jwtTokenOptions.Subject)
.AddClaim(ClaimName.IssuedAt, UnixEpoch.GetSecondsSince(new DateTimeOffset(DateTime.UtcNow)))
.ExpirationTime(DateTime.Now.AddSeconds(_jwtTokenOptions.ExpSecond));
if (claimDic is not null)
{
foreach (var d in claimDic)
{
token.AddClaim(d.Key, d.Value);
};
}
return token.Encode();
}
public IDictionary<string, object>? VerifyToken(string token, TokenVerifyErrorAction tokenVerifyErrorAction)
{
IDictionary<string, object>? claimDic = null;
try
{
claimDic = JwtBuilder.Create()
.WithAlgorithm(new RS256Algorithm(RSAFileHelper.GetPublicKey()))
.WithValidationParameters(ValidationParameters.Default)
.Decode<IDictionary<string, object>>(token);
}
catch (TokenNotYetValidException ex)
{
if (tokenVerifyErrorAction.TokenNotYetValidAction is not null)
{
tokenVerifyErrorAction.TokenNotYetValidAction(ex);
}
//Console.WriteLine("Token错误");
}
catch (TokenExpiredException ex)
{
if (tokenVerifyErrorAction.TokenExpiredAction is not null)
{
tokenVerifyErrorAction.TokenExpiredAction(ex);
}
//Console.WriteLine("Token过期");
}
catch (SignatureVerificationException ex)
{
if (tokenVerifyErrorAction.SignatureVerificationAction is not null)
{
tokenVerifyErrorAction.SignatureVerificationAction(ex);
}
//Console.WriteLine("Token无效");
}
catch (Exception ex)
{
if (tokenVerifyErrorAction.ErrorAction is not null)
{
tokenVerifyErrorAction.ErrorAction(ex);
}
//Console.WriteLine("Token内部错误json序列化");
}
return claimDic;
}
public class TokenVerifyErrorAction
{
public Action<TokenNotYetValidException>? TokenNotYetValidAction { get; set; }
public Action<TokenExpiredException>? TokenExpiredAction { get; set; }
public Action<SignatureVerificationException>? SignatureVerificationAction { get; set; }
public Action<Exception>? ErrorAction { get; set; }
}
}
}

View File

@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.Auth.JwtBearer.Authentication.Options
{
public class JwtTokenOptions
{
/// <summary>
/// 听众
/// </summary>
public string Audience { get; set; } = string.Empty;
/// <summary>
/// 发行者
/// </summary>
public string Issuer { get; set; } = string.Empty;
/// <summary>
/// 主题
/// </summary>
public string Subject { get; set; } = string.Empty;
/// <summary>
/// 过期时间,单位秒
/// </summary>
public long ExpSecond { get; set; }
}
}

View File

@@ -3,14 +3,17 @@ using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Primitives;
using System.Net;
using System.Security.Claims;
using System.Text.Json;
using Yi.Framework.Core.Helper;
namespace Yi.Framework.Authentication.JwtBearer
namespace Yi.Framework.Auth.JwtBearer.Authentication
{
public class YiJwtAuthenticationHandler : IAuthenticationHandler
{
public YiJwtAuthenticationHandler()
private JwtTokenManager _jwtTokenManager;
public YiJwtAuthenticationHandler(JwtTokenManager jwtTokenManager)
{
_jwtTokenManager = jwtTokenManager;
}
public const string YiJwtSchemeName = "YiJwtAuth";
@@ -36,13 +39,26 @@ namespace Yi.Framework.Authentication.JwtBearer
/// <param name="name"></param>
/// <param name="role"></param>
/// <returns></returns>
private AuthenticationTicket GetAuthTicket(string name, string role)
private AuthenticationTicket GetAuthTicket(IDictionary<string, object> dicClaims)
{
var claimsIdentity = new ClaimsIdentity(new Claim[]
List<Claim> claims = new List<Claim>();
foreach (var claim in dicClaims)
{
new Claim(ClaimTypes.Name, name),
new Claim(ClaimTypes.Role, role),
}, YiJwtSchemeName);
var p = (JsonElement)claim.Value;
string? resp=null;
switch (p.ValueKind)
{
case JsonValueKind.String:
resp = p.GetString();
break;
case JsonValueKind.Number:
resp = p.GetInt32().ToString();
break;
}
claims.Add(new Claim(claim.Key, resp ?? ""));
}
var claimsIdentity = new ClaimsIdentity(claims.ToArray(), YiJwtSchemeName);
var principal = new ClaimsPrincipal(claimsIdentity);
return new AuthenticationTicket(principal, _scheme.Name);
}
@@ -54,29 +70,34 @@ namespace Yi.Framework.Authentication.JwtBearer
/// <exception cref="NotImplementedException"></exception>
public Task<AuthenticateResult> AuthenticateAsync()
{
AuthenticateResult result;
AuthenticateResult result = AuthenticateResult.Fail("未发现授权令牌");
_context.Request.Headers.TryGetValue("Authorization", out StringValues values);
string valStr = values.ToString();
if (!string.IsNullOrWhiteSpace(valStr))
{
//认证模拟basic认证cusAuth YWRtaW46YWRtaW4=
string[] authVal = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(valStr.Substring(YiJwtSchemeName.Length + 1))).Split(':');
//var loginInfo = new Dto.LoginDto() { Username = authVal[0], Password = authVal[1] };
//var validVale = _userService.IsValid(loginInfo);
bool validVale = true;
if (!validVale)
result = AuthenticateResult.Fail("未登陆");
var tokenHeader = valStr.Substring(0, 6);
if (tokenHeader == "Bearer")
{
var token = valStr.Substring(7);
var claimDic = _jwtTokenManager.VerifyToken(token, new JwtTokenManager.TokenVerifyErrorAction()
{
TokenExpiredAction = (ex) => { result = AuthenticateResult.Fail("Token过期"); },
SignatureVerificationAction = (ex) => { result = AuthenticateResult.Fail("Token效验失效"); },
TokenNotYetValidAction = (ex) => { result = AuthenticateResult.Fail("Token完全错误"); },
ErrorAction = (ex) => { result = AuthenticateResult.Fail("Token内部错误"); }
});
if (claimDic is not null)
{
//成功
result = AuthenticateResult.Success(GetAuthTicket(claimDic));
}
}
else
{
//这里应该将token进行效验然后加入解析的claim中即可
var ticket = GetAuthTicket("cc", "admin");
result = AuthenticateResult.Success(ticket);
result = AuthenticateResult.Fail("授权令牌格式错误");
}
}
else
{
result = AuthenticateResult.Fail("未登陆");
}
return Task.FromResult(result);
}

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Core.CurrentUsers;
namespace Yi.Framework.Auth.JwtBearer.Authorization
{
public class DefaultPermissionHandler : IPermissionHandler
{
public bool IsPass(string permission, ICurrentUser currentUser)
{
return true;
}
}
}

View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Core.CurrentUsers;
namespace Yi.Framework.Auth.JwtBearer.Authorization
{
public interface IPermissionHandler
{
bool IsPass(string permission,ICurrentUser currentUser);
}
}

View File

@@ -0,0 +1,47 @@
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Core.CurrentUsers;
using Yi.Framework.Core.Exceptions;
using Yi.Framework.Core.Model;
namespace Yi.Framework.Auth.JwtBearer.Authorization
{
[AttributeUsage(AttributeTargets.Method)]
public class PermissionAttribute : ActionFilterAttribute
{
private string Permission { get; set; }
public PermissionAttribute(string permission)
{
this.Permission = permission;
}
/// <summary>
/// 动作鉴权
/// </summary>
/// <param name="context"></param>
/// <exception cref="Exception"></exception>
public override void OnActionExecuting(ActionExecutingContext context)
{
var permissionHandler = ServiceLocatorModel.Instance.GetRequiredService<IPermissionHandler>();
var currentUser = ServiceLocatorModel.Instance.GetRequiredService<ICurrentUser>();
var result = permissionHandler.IsPass(Permission, currentUser);
if (!result)
{
throw new AuthException(message: "您无权限访问该接口");
}
}
}
}

View File

@@ -6,8 +6,13 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="JWT" Version="10.0.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Yi.Framework.AspNetCore\Yi.Framework.AspNetCore.csproj" />
<ProjectReference Include="..\Yi.Framework.Core\Yi.Framework.Core.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,41 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using StartupModules;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Auth.JwtBearer.Authentication;
using Yi.Framework.Auth.JwtBearer.Authentication.Options;
using Yi.Framework.Auth.JwtBearer.Authorization;
using Yi.Framework.Core;
using Yi.Framework.Core.Attributes;
using Yi.Framework.Core.Configuration;
namespace Yi.Framework.Auth.JwtBearer
{
[DependsOn(typeof(YiFrameworkCoreModule))]
public class YiFrameworkAuthJwtBearerModule : IStartupModule
{
public void Configure(IApplicationBuilder app, ConfigureMiddlewareContext context)
{
}
public void ConfigureServices(IServiceCollection services, ConfigureServicesContext context)
{
services.Configure<JwtTokenOptions>(Appsettings.appConfiguration("JwtTokenOptions"));
services.AddAuthentication(YiJwtAuthenticationHandler.YiJwtSchemeName);
services.AddTransient<JwtTokenManager>();
services.AddSingleton<IPermissionHandler, DefaultPermissionHandler>();
services.AddAuthentication(option =>
{
option.AddScheme<YiJwtAuthenticationHandler>(YiJwtAuthenticationHandler.YiJwtSchemeName, YiJwtAuthenticationHandler.YiJwtSchemeName);
});
services.AddSingleton<PermissionAttribute>(_=>new PermissionAttribute(string.Empty));
services.AddControllers(options => {
options.Filters.Add<PermissionAttribute>();
});
}
}
}

View File

@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.Core.Const
{
public class TokenTypeConst
{
public const string Id = nameof(Id);
public const string UserName= nameof(UserName);
public const string TenantId = nameof(TenantId);
public const string Email = nameof(Email);
public const string PhoneNumber = nameof(PhoneNumber);
public const string Roles = nameof(Roles);
public const string Permission = nameof(Permission);
}
}

View File

@@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.Core.CurrentUser
namespace Yi.Framework.Core.CurrentUsers
{
public class CurrentUser : ICurrentUser
{

View File

@@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.Core.CurrentUser
namespace Yi.Framework.Core.CurrentUsers
{
public interface ICurrentUser
{

View File

@@ -0,0 +1,52 @@
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Core.Enums;
namespace Yi.Framework.Core.Exceptions
{
public class AuthException : Exception,
IHasErrorCode,
IHasErrorDetails,
IHasLogLevel
{
public ResultCodeEnum Code { get; set; }
public string? Details { get; set; }
public LogLevel LogLevel { get; set; }
public AuthException(
ResultCodeEnum code = ResultCodeEnum.NoPermission,
string? message = null,
string? details = null,
Exception? innerException = null,
LogLevel logLevel = LogLevel.Warning)
: base(message, innerException)
{
Code = code;
Details = details;
LogLevel = logLevel;
}
/// <summary>
/// 序列化参数的构造函数
/// </summary>
public AuthException(SerializationInfo serializationInfo, StreamingContext context)
: base(serializationInfo, context)
{
}
public AuthException WithData(string name, object value)
{
Data[name] = value;
return this;
}
}
}

View File

@@ -9,7 +9,8 @@ using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Core.CurrentUser;
using Yi.Framework.Core.Const;
using Yi.Framework.Core.CurrentUsers;
namespace Yi.Framework.Core.Extensions
{
@@ -17,7 +18,7 @@ namespace Yi.Framework.Core.Extensions
{
public static IServiceCollection AddCurrentUserServer(this IServiceCollection services)
{
return services.AddScoped<ICurrentUser, CurrentUser.CurrentUser>();
return services.AddScoped<ICurrentUser, CurrentUser>();
}
@@ -51,10 +52,10 @@ namespace Yi.Framework.Core.Extensions
var claims = authenticateContext.Principal.Claims;
//通过鉴权之后,开始赋值
_currentUser.IsAuthenticated = true;
//_currentUser.Id = claims.GetClaim(JwtRegisteredClaimNames.Sid) is null ? 0 : Convert.ToInt64(claims.GetClaim(JwtRegisteredClaimNames.Sid));
//_currentUser.UserName = claims.GetClaim(SystemConst.UserName) ?? "";
//_currentUser.Permission = claims.GetClaims(SystemConst.PermissionClaim);
//_currentUser.TenantId = claims.GetClaim(SystemConst.TenantId) is null ? null : Guid.Parse(claims.GetClaim(SystemConst.TenantId)!);
_currentUser.Id = claims.GetClaim(TokenTypeConst.Id) is null ? 0 : Convert.ToInt64(claims.GetClaim(TokenTypeConst.Id));
_currentUser.UserName = claims.GetClaim(TokenTypeConst.UserName) ?? "";
_currentUser.Permission = claims.GetClaims(TokenTypeConst.Permission);
_currentUser.TenantId = claims.GetClaim(TokenTypeConst.TenantId) is null ? null : Guid.Parse(claims.GetClaim(TokenTypeConst.TenantId)!);
await _next(context);
}

View File

@@ -8,7 +8,7 @@ namespace Yi.Framework.Core.Model
{
public static class ServiceLocatorModel
{
public static IServiceProvider? Instance { get; set; }
public static IServiceProvider Instance { get; set; }
}
}

View File

@@ -8,6 +8,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yi.Framework.Core.Configuration;
using Yi.Framework.Core.CurrentUsers;
using Yi.Framework.Core.Extensions;
using Yi.Framework.Core.Model;
@@ -22,6 +23,8 @@ namespace Yi.Framework.Core
//全局错误,需要靠前,放在此处无效
//app.UseErrorHandlingServer();
app.UseCurrentUserServer();
}
public void ConfigureServices(IServiceCollection services, ConfigureServicesContext context)
@@ -31,6 +34,7 @@ namespace Yi.Framework.Core
//全盘扫描,自动依赖注入
services.AddAutoIocServer();
services.AddCurrentUserServer();
//全局日志
GobalLogModel.SqlLogEnable = Appsettings.appBool("SqlLog_Enable");
GobalLogModel.LoginCodeEnable = Appsettings.appBool("LoginCode_Enable");

View File

@@ -9,6 +9,12 @@
服务实现
</summary>
</member>
<member name="M:Yi.Framework.Application.Student.StudentService.GetToken">
<summary>
测试token
</summary>
<returns></returns>
</member>
<member name="M:Yi.Framework.Application.Student.StudentService.PostUow">
<summary>
Uow

View File

@@ -16,6 +16,11 @@ using Yi.Framework.Ddd.Services;
using Yi.Framework.Core.Attributes;
using Yi.Framework.Uow;
using Microsoft.AspNetCore.Authorization;
using Yi.Framework.Auth.JwtBearer.Authentication;
using Yi.Framework.Core.Const;
using Yi.Framework.Core.CurrentUsers;
using Yi.Framework.Auth.JwtBearer.Authorization;
using Yi.Framework.Domain.Shared.Student.ConstClasses;
namespace Yi.Framework.Application.Student
{
@@ -29,22 +34,37 @@ namespace Yi.Framework.Application.Student
{
private readonly IStudentRepository _studentRepository;
private readonly StudentManager _studentManager;
//private readonly IUnitOfWorkManager _unitOfWorkManager;
public StudentService(IStudentRepository studentRepository, StudentManager studentManager, IUnitOfWorkManager unitOfWorkManager)
private readonly IUnitOfWorkManager _unitOfWorkManager;
private readonly JwtTokenManager _jwtTokenManager;
private readonly ICurrentUser _currentUser;
public StudentService(IStudentRepository studentRepository, StudentManager studentManager, IUnitOfWorkManager unitOfWorkManager, JwtTokenManager jwtTokenManager, ICurrentUser currentUser)
{
_studentRepository = studentRepository;
_studentManager = studentManager;
_unitOfWorkManager = unitOfWorkManager;
_jwtTokenManager = jwtTokenManager;
_currentUser=currentUser;
}
/// <summary>
/// 测试token
/// </summary>
/// <returns></returns>
public string GetToken()
{
var claimDic = new Dictionary<string, object>() { { TokenTypeConst.Id, "123" }, { TokenTypeConst.UserName, "cc" } };
return _jwtTokenManager.CreateToken(claimDic);
}
private readonly IUnitOfWorkManager _unitOfWorkManager;
/// <summary>
/// Uow
/// </summary>
/// <returns></returns>
[Authorize]
[Permission(AuthStudentConst.查询)]
public async Task<StudentGetOutputDto> PostUow()
{
var o= _currentUser;
StudentGetOutputDto res = new();
using (var uow = _unitOfWorkManager.CreateContext())
{

View File

@@ -9,6 +9,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\framework\Yi.Framework.Auth.JwtBearer\Yi.Framework.Auth.JwtBearer.csproj" />
<ProjectReference Include="..\..\src\framework\Yi.Framework.Uow\Yi.Framework.Uow.csproj" />
<ProjectReference Include="..\Yi.Framework.Application.Contracts\Yi.Framework.Application.Contracts.csproj" />
<ProjectReference Include="..\Yi.Framework.Domain\Yi.Framework.Domain.csproj" />

View File

@@ -9,6 +9,7 @@ using System.Threading.Tasks;
using Yi.Framework.Application.Contracts;
using Yi.Framework.Application.Contracts.Student;
using Yi.Framework.Application.Student;
using Yi.Framework.Auth.JwtBearer;
using Yi.Framework.Core.Attributes;
using Yi.Framework.Domain;
@@ -16,7 +17,8 @@ namespace Yi.Framework.Application
{
[DependsOn(
typeof(YiFrameworkApplicationContractsModule),
typeof(YiFrameworkDomainModule)
typeof(YiFrameworkDomainModule),
typeof(YiFrameworkAuthJwtBearerModule)
)]
public class YiFrameworkApplicationModule : IStartupModule
{

View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Yi.Framework.Domain.Shared.Student.ConstClasses
{
public class AuthStudentConst
{
public const string = "student:student:list";
public const string = "student:student:add";
}
}

View File

@@ -1,5 +1,4 @@
using AspNetCore.Microsoft.AspNetCore.Hosting;
using Yi.Framework.Authentication.JwtBearer;
using Yi.Framework.Core.Autofac.Extensions;
using Yi.Framework.Core.Autofac.Modules;
using Yi.Framework.Core.Extensions;
@@ -14,12 +13,7 @@ builder.WebHost.UseStartUrlsServer(builder.Configuration);
//<2F><><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>
builder.UseYiModules(typeof(YiFrameworkWebModule));
builder.Services.AddAuthentication(YiJwtAuthenticationHandler.YiJwtSchemeName);
builder.Services.AddAuthentication(option =>
{
option.AddScheme<YiJwtAuthenticationHandler>(YiJwtAuthenticationHandler.YiJwtSchemeName, YiJwtAuthenticationHandler.YiJwtSchemeName);
});
//<2F><><EFBFBD><EFBFBD>autofacģ<63><C4A3>,<2C><>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>
builder.Host.ConfigureAutoFacContainer(container =>
{

View File

@@ -7,10 +7,18 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\framework\Yi.Framework.Authentication.JwtBearer\Yi.Framework.Authentication.JwtBearer.csproj" />
<ProjectReference Include="..\..\src\framework\Yi.Framework.Core.Autofac\Yi.Framework.Core.Autofac.csproj" />
<ProjectReference Include="..\Yi.Framework.Application\Yi.Framework.Application.csproj" />
<ProjectReference Include="..\Yi.Framework.Sqlsugar\Yi.Framework.Sqlsugar.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="key.pem">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="public.pem">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@@ -1,6 +1,7 @@
using AspNetCore.Microsoft.AspNetCore.Builder;
using StartupModules;
using Yi.Framework.Application;
using Yi.Framework.Auth.JwtBearer;
using Yi.Framework.Core;
using Yi.Framework.Core.Attributes;
using Yi.Framework.Sqlsugar;

View File

@@ -25,5 +25,14 @@
"server=[xxxx];port=3306;database=[xxxx];user id=[xxxx];password=[xxxx]", //mysql
"Data Source=[xxxx];Initial Catalog=[xxxx];User ID=[xxxx];password=[xxxx]" //sqlserver
]
},
"JwtTokenOptions": {
"Audience": "yi",
"Issuer": "localhost:19002",
"Subject": "yiframwork",
"ExpSecond": 3600
}
}

View File

@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC7VJTUt9Us8cKj
MzEfYyjiWA4R4/M2bS1GB4t7NXp98C3SC6dVMvDuictGeurT8jNbvJZHtCSuYEvu
NMoSfm76oqFvAp8Gy0iz5sxjZmSnXyCdPEovGhLa0VzMaQ8s+CLOyS56YyCFGeJZ
qgtzJ6GR3eqoYSW9b9UMvkBpZODSctWSNGj3P7jRFDO5VoTwCQAWbFnOjDfH5Ulg
p2PKSQnSJP3AJLQNFNe7br1XbrhV//eO+t51mIpGSDCUv3E0DDFcWDTH9cXDTTlR
ZVEiR2BwpZOOkE/Z0/BVnhZYL71oZV34bKfWjQIt6V/isSMahdsAASACp4ZTGtwi
VuNd9tybAgMBAAECggEBAKTmjaS6tkK8BlPXClTQ2vpz/N6uxDeS35mXpqasqskV
laAidgg/sWqpjXDbXr93otIMLlWsM+X0CqMDgSXKejLS2jx4GDjI1ZTXg++0AMJ8
sJ74pWzVDOfmCEQ/7wXs3+cbnXhKriO8Z036q92Qc1+N87SI38nkGa0ABH9CN83H
mQqt4fB7UdHzuIRe/me2PGhIq5ZBzj6h3BpoPGzEP+x3l9YmK8t/1cN0pqI+dQwY
dgfGjackLu/2qH80MCF7IyQaseZUOJyKrCLtSD/Iixv/hzDEUPfOCjFDgTpzf3cw
ta8+oE4wHCo1iI1/4TlPkwmXx4qSXtmw4aQPz7IDQvECgYEA8KNThCO2gsC2I9PQ
DM/8Cw0O983WCDY+oi+7JPiNAJwv5DYBqEZB1QYdj06YD16XlC/HAZMsMku1na2T
N0driwenQQWzoev3g2S7gRDoS/FCJSI3jJ+kjgtaA7Qmzlgk1TxODN+G1H91HW7t
0l7VnL27IWyYo2qRRK3jzxqUiPUCgYEAx0oQs2reBQGMVZnApD1jeq7n4MvNLcPv
t8b/eU9iUv6Y4Mj0Suo/AU8lYZXm8ubbqAlwz2VSVunD2tOplHyMUrtCtObAfVDU
AhCndKaA9gApgfb3xw1IKbuQ1u4IF1FJl3VtumfQn//LiH1B3rXhcdyo3/vIttEk
48RakUKClU8CgYEAzV7W3COOlDDcQd935DdtKBFRAPRPAlspQUnzMi5eSHMD/ISL
DY5IiQHbIH83D4bvXq0X7qQoSBSNP7Dvv3HYuqMhf0DaegrlBuJllFVVq9qPVRnK
xt1Il2HgxOBvbhOT+9in1BzA+YJ99UzC85O0Qz06A+CmtHEy4aZ2kj5hHjECgYEA
mNS4+A8Fkss8Js1RieK2LniBxMgmYml3pfVLKGnzmng7H2+cwPLhPIzIuwytXywh
2bzbsYEfYx3EoEVgMEpPhoarQnYPukrJO4gwE2o5Te6T5mJSZGlQJQj9q4ZB2Dfz
et6INsK0oG8XVGXSpQvQh3RUYekCZQkBBFcpqWpbIEsCgYAnM3DQf3FJoSnXaMhr
VBIovic5l0xFkEHskAjFTevO86Fsz1C2aSeRKSqGFoOQ0tmJzBEs1R6KqnHInicD
TQrKhArgLXX4v3CddjfTRJkFWDbE/CkvKZNOrcf1nhaGCPspRJj2KUkj1Fhl9Cnc
dn/RsYEONbwQSjIfMPkvxF+8HQ==
-----END PRIVATE KEY-----

View File

@@ -0,0 +1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu1SU1LfVLPHCozMxH2Mo
4lgOEePzNm0tRgeLezV6ffAt0gunVTLw7onLRnrq0/IzW7yWR7QkrmBL7jTKEn5u
+qKhbwKfBstIs+bMY2Zkp18gnTxKLxoS2tFczGkPLPgizskuemMghRniWaoLcyeh
kd3qqGElvW/VDL5AaWTg0nLVkjRo9z+40RQzuVaE8AkAFmxZzow3x+VJYKdjykkJ
0iT9wCS0DRTXu269V264Vf/3jvredZiKRkgwlL9xNAwxXFg0x/XFw005UWVRIkdg
cKWTjpBP2dPwVZ4WWC+9aGVd+Gyn1o0CLelf4rEjGoXbAAEgAqeGUxrcIlbjXfbc
mwIDAQAB
-----END PUBLIC KEY-----