添加项目文件。

This commit is contained in:
DK
2022-03-28 15:27:40 +08:00
parent b620fcb0cf
commit dc78fd1a09
898 changed files with 173053 additions and 0 deletions
@@ -0,0 +1,12 @@
{
"version": 1,
"isRoot": true,
"tools": {
"dotnet-ef": {
"version": "5.0.10",
"commands": [
"dotnet-ef"
]
}
}
}
@@ -0,0 +1,204 @@
using System;
using System.IO;
using System.Security.Cryptography;
using IRaCIS.Core.Infrastructure.Extention;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using ZhiZhun.AuthenticationCenter.Utility;
using ZhiZhun.AuthenticationCenter.Utility.RSA;
namespace Zhaoxi.NET6.AuthenticationCenter.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class JWTController : ControllerBase
{
#region MyRegion
private ILogger<JWTController> _logger = null;
private IJWTService _iJWTService = null;
private readonly IConfiguration _iConfiguration;
public JWTController(ILoggerFactory factory,
ILogger<JWTController> logger,
IConfiguration configuration
, IJWTService service)
{
this._logger = logger;
this._iConfiguration = configuration;
this._iJWTService = service;
}
#endregion
[Route("GetKey")]
[HttpGet]
public string GetKey()
{
string keyDir = Directory.GetCurrentDirectory();
if (RSAHelper.TryGetKeyParameters(keyDir, false, out RSAParameters keyParams) == false)
{
keyParams = RSAHelper.GenerateAndSaveKey(keyDir, false);
}
return JsonConvert.SerializeObject(keyParams);
}
/// <summary>
/// 数据库校验
/// </summary>
/// <param name="name"></param>
/// <param name="password"></param>
/// <returns></returns>
[Route("Login")]
[HttpPost]
public IResponseOutput Login([FromForm] string name, [FromForm] string password)
{
Console.WriteLine($"This is Login name={name} password={password}");
if ("Eleven".Equals(name, StringComparison.OrdinalIgnoreCase) && "123456".Equals(password))//应该数据库
{
UserBasicInfo currentUser = new UserBasicInfo()
{
//Id = 123,
//Account = "xuyang@zhaoxiEdu.Net",
//EMail = "57265177@qq.com",
//Mobile = "18664876671",
//Sex = 1,
//Age = 33,
//Name = "Eleven",
//Role = "Admin"
};
string token = this._iJWTService.GetToken(currentUser);
if (!string.IsNullOrEmpty(token))
{
return ResponseOutput.Ok("Token颁发成功");
}
else
{
return ResponseOutput.NotOk("Token获取失败");
}
}
else
{
return ResponseOutput.NotOk("验证失败");
}
}
/// <summary>
/// 生成Token+RefreshToken
/// </summary>
/// <param name="name"></param>
/// <param name="password"></param>
/// <returns></returns>
[Route("LoginWithRefresh")]
[HttpPost]
public IResponseOutput LoginWithRefresh([FromForm] string name, [FromForm] string password)
{
Console.WriteLine($"This is LoginWithRefresh name={name} password={password}");
if ("Eleven".Equals(name, StringComparison.OrdinalIgnoreCase) && "123456".Equals(password))//应该数据库
{
UserBasicInfo currentUser = new UserBasicInfo()
{
//Id = 123,
//Account = "xuyang@zhaoxiEdu.Net",
//EMail = "57265177@qq.com",
//Mobile = "18664876671",
//Sex = 1,
//Age = 33,
//Name = "Eleven",
//Role = "Admin"
};
var tokenPair = this._iJWTService.GetTokenWithRefresh(currentUser);
if (tokenPair != null && !string.IsNullOrEmpty(tokenPair.Item1))
{
return ResponseOutput.Ok(new {
Token = tokenPair.Item1,
RefreshToken = tokenPair.Item2});
}
else
{
return ResponseOutput.NotOk("颁发token失败");
}
}
else
{
return ResponseOutput.NotOk("验证失败");
}
}
[Route("RefreshToken")]
[HttpPost]
public IResponseOutput RefreshToken([FromForm] string refreshToken)
{
var token = this._iJWTService.GetTokenByRefresh(refreshToken);
if (!string.IsNullOrEmpty(token))
{
return ResponseOutput.Ok("刷新Token成功");
}
else
{
return ResponseOutput.NotOk("刷新token失败");
}
#region Check refreshToken
//string sResult = JWTTokenDeserialize.AnalysisToken(refreshToken);
//var refreshTokenResult = await base.HttpContext.AuthenticateAsync(JwtBearerDefaults.AuthenticationScheme);
//var expires = refreshTokenResult?.Principal?.Claims?.First(c => c.Type.Equals("expires"))?.Value ?? DateTime.Now.AddMinutes(-1).ToString();
//if (DateTime.Parse(expires) > DateTime.Now)//有效期验证
//{
// var token = this._iJWTService.GetTokenByRefresh(refreshToken);
// if (!string.IsNullOrEmpty(token))
// {
// return JsonConvert.SerializeObject(new AjaxResult<string>()
// {
// Result = true,
// Message = "刷新Token成功",
// TValue = token,
// OtherValue = refreshToken//写在OtherValue
// });
// }
// else
// {
// return JsonConvert.SerializeObject(new AjaxResult<string>()
// {
// Result = false,
// Message = "刷新token失败",
// TValue = ""
// });
// }
//}
//else
//{
// return JsonConvert.SerializeObject(new AjaxResult<string>()
// {
// Result = false,
// Message = "RefreshToken过期了",
// TValue = ""
// });
//}
#endregion
}
}
}
@@ -0,0 +1,39 @@
using System;
using System.Threading.Tasks;
using Grpc.Core;
using gRPC.ZHiZHUN.AuthServer.protos;
using ZhiZhun.AuthenticationCenter.User;
using ZhiZhun.AuthenticationCenter.Utility;
namespace ZhiZhun.AuthenticationCenter.GrpcService
{
public class GrpcTokenService: TokenGrpcService.TokenGrpcServiceBase
{
private readonly IJWTService _jwtService;
public GrpcTokenService(IJWTService jwtService)
{
_jwtService = jwtService;
}
public override Task<GetTokenResponse> GetUserToken(GetTokenReuqest request, ServerCallContext context)
{
string token = _jwtService.GetToken(new UserBasicInfo()
{
Id = Guid.Parse(request.Id),
RealName = request.RealName,
ReviewerCode = request.ReviewerCode,
UserName = request.UserName,
UserTypeEnum = (UserType)request.UserTypeEnumInt,
UserTypeShortName = request.UserTypeShortName
});
return Task.FromResult(new GetTokenResponse(){Code = 1,Token = token });
}
}
}
@@ -0,0 +1,38 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<LangVersion>default</LangVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DocumentationFile>D:\新工作\IRaCIS\IRaCIS.Core5.0.API\ZhiZhunAuthenticationCenter\ZhiZhun.AuthenticationCenter.xml</DocumentationFile>
<NoWarn>1701;1702;1591;</NoWarn>
</PropertyGroup>
<ItemGroup>
<None Remove="Protos\GrpcToken.proto" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Grpc.AspNetCore" Version="2.40.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="6.0.0" />
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="6.15.0" />
<PackageReference Include="Serilog" Version="2.10.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.0.1" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="6.2.3" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="6.2.3" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.15.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\IRaCIS.Core.Infrastructure\IRaCIS.Core.Infrastructure.csproj" />
</ItemGroup>
<ItemGroup>
<Protobuf Include="Protos\GrpcToken.proto" GrpcServices="Server" />
</ItemGroup>
</Project>
+62
View File
@@ -0,0 +1,62 @@
using System;
using System.Security.Authentication;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Extensions.Configuration;
using Serilog;
using ZhiZhun.AuthenticationCenter;
namespace Zhaoxi.NET6.AuthenticationCenter
{
public class Program
{
public static void Main(string[] args)
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.WriteTo.File("logs\\log.txt",
rollingInterval: RollingInterval.Day,
rollOnFileSizeLimit: true)
.CreateLogger();
try
{
CreateHostBuilder(args).Build().Run();
}
catch (Exception e)
{
Log.Information(e.ToString());
}
}
public static IHostBuilder CreateHostBuilder(string[] args)
{
var configuration = new ConfigurationBuilder().SetBasePath(Environment.CurrentDirectory)
.AddJsonFile("appsettings.json")
.Build();
return Host.CreateDefaultBuilder(args)
.UseWindowsService()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.ConfigureKestrel(options =>
{
//如果放在内网,不想用https 那么需要在这里设置
//Setup a HTTP / 2 endpoint without TLS.
options.ListenLocalhost(7200, o => o.Protocols =
HttpProtocols.Http2);
});
webBuilder.UseUrls(configuration["ApplicationUrl"]);
webBuilder.UseStartup<Startup>();
});
}
}
}
@@ -0,0 +1,16 @@
{
"profiles": {
"ZhiZhun.AuthenticationCenter": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"dotnetRunMessages": true,
"applicationUrl": "http://localhost:7200"
}
}
}
@@ -0,0 +1,69 @@
// 使用的是proto3版本
syntax = "proto3";
// 定义命名空间,后续生成代码时就会生成对应的命名空间
option csharp_namespace = "gRPC.ZHiZHUN.AuthServer.protos";
/*
每一句需要用分号结尾
message 用来定义请求和返回数据格式
tag message后面的值数字代表是字段的标识(tag),不是赋值,
*/
// 新增用户时需要传递数据消息, 可理解为一个类
message GetTokenReuqest{
string id=1;
string userName=2;
string realName=3;
string reviewerCode=4;
int32 userTypeEnumInt=5;
string userTypeShortName=6;
bool isAdmin=7;
}
// 新增时返回的消息格式
message GetTokenResponse {
int32 code=1;
string token =2;
}
// service 用标识定义服务的,里面写对应的方法
service TokenGrpcService{
// 获取token
rpc GetUserToken(GetTokenReuqest) returns (GetTokenResponse);
}
/*
// 新增用户时需要传递数据消息, 可理解为一个类
message AddUserReuqest{
string name=1;
int32 age=2;
bool isBoy=3;
}
// 新增时返回的消息格式
message ResultResponse {
int32 code=1;
string msg =2;
}
//传递的查询条件信息格式,可理解为平时传入的查询条件对象
message QueryUserReuqest{
string name=1;
}
//查询返回的用户信息格式,可理解为返回的类
message UserInfoResponse {
string name=1;
int32 age=2;
string gender=3;
}
// service 用标识定义服务的,里面写对应的方法
service UserService{
// 新增用户
rpc AddUser(AddUserReuqest) returns (ResultResponse);
// 查询用户
rpc GetAllUser(QueryUserReuqest) returns (UserInfoResponse);
}
*/
+77
View File
@@ -0,0 +1,77 @@
using System.IO;
using System.Security.Cryptography;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
using ZhiZhun.AuthenticationCenter.GrpcService;
using ZhiZhun.AuthenticationCenter.Utility;
using ZhiZhun.AuthenticationCenter.Utility.RSA;
namespace ZhiZhun.AuthenticationCenter
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers()
.AddNewtonsoftJson();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "ZHIZHUN.AuthenticationCenter", Version = "v1" });
});
#region HS256
//services.AddScoped<IJWTService, JWTHSService>();
//services.Configure<JWTTokenOptions>(this.Configuration.GetSection("JWTTokenOptions"));
#endregion
#region RS256
string keyDir = Directory.GetCurrentDirectory();
if (RSAHelper.TryGetKeyParameters(keyDir, true, out RSAParameters keyParams) == false)
{
keyParams = RSAHelper.GenerateAndSaveKey(keyDir);
}
services.AddScoped<IJWTService, JWTRSService>();
services.Configure<JWTTokenOptions>(this.Configuration.GetSection("JWTTokenOptions"));
#endregion
services.AddGrpc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "ZHIZHUN.AuthenticationCenter v1"));
app.UseRouting();
//app.UseAuthentication();
//app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
//endpoints.MapControllers();
endpoints.MapGrpcService<GrpcTokenService>();
});
}
}
}
@@ -0,0 +1,19 @@
using System;
using ZhiZhun.AuthenticationCenter.User;
namespace ZhiZhun.AuthenticationCenter.Utility
{
public class UserBasicInfo
{
public Guid Id { get; set; }
public string UserName { get; set; } = string.Empty;
public string RealName { get; set; } = string.Empty;
public UserType UserTypeEnum { get; set; }
public string ReviewerCode { get; set; } = string.Empty;
public string UserTypeShortName { get; set; } = string.Empty;
}
}
@@ -0,0 +1,37 @@
namespace ZhiZhun.AuthenticationCenter.User
{
public enum UserType
{
//PM
ProjectManager = 1,
//CRC
ClinicalResearchCoordinator = 2,
//IQA
IQC = 3,
////简历管理人员
//ResumeManager=4,
////简历运维人员
//ReviewerCoordinator = 5,
ReviewerCoordinator = 4,
// 大屏展示
Dashboard = 6,
// 超级管理员用户类型,用于取代 SuperAdmin字段 数据库不内置这个用户类型和角色的配置,因为只允许有一个
SuperAdmin = 8,
//医生用户类型暂不处理
ShareImage = 9,
Undefined = 0
}
}
@@ -0,0 +1,31 @@
using System;
namespace ZhiZhun.AuthenticationCenter.Utility
{
/// <summary>
/// 简单封装个注入
/// </summary>
public interface IJWTService
{
/// <summary>
/// 用户信息
/// </summary>
/// <param name="userInfo"></param>
/// <returns></returns>
string GetToken(UserBasicInfo userInfo);
/// <summary>
/// 获取Token+RefreshToken
/// </summary>
/// <param name="userInfo"></param>
/// <returns>Token+RefreshToken</returns>
Tuple<string, string> GetTokenWithRefresh(UserBasicInfo userInfo);
/// <summary>
/// 基于refreshToken获取Token
/// </summary>
/// <param name="refreshToken"></param>
/// <returns></returns>
string GetTokenByRefresh(string refreshToken);
}
}
@@ -0,0 +1,103 @@
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using ZhiZhun.AuthenticationCenter.User;
namespace ZhiZhun.AuthenticationCenter.Utility
{
/// <summary>
/// 对称可逆加密
/// </summary>
public class JWTHSService : IJWTService
{
private static Dictionary<string, UserBasicInfo> TokenCache = new Dictionary<string, UserBasicInfo>();
#region Option注入
private readonly JWTTokenOptions _JWTTokenOptions;
public JWTHSService(IOptionsMonitor<JWTTokenOptions> jwtTokenOptions)
{
this._JWTTokenOptions = jwtTokenOptions.CurrentValue;
}
#endregion
public string GetToken(UserBasicInfo userModel)
{
return this.IssueToken(userModel);
}
/// <summary>
/// 刷新token的有效期问题上端校验
/// </summary>
/// <param name="refreshToken"></param>
/// <returns></returns>
public string GetTokenByRefresh(string refreshToken)
{
if (TokenCache.ContainsKey(refreshToken))
{
string token = this.IssueToken(TokenCache[refreshToken], 60);
return token;
}
else
{
return "";
}
}
/// <summary>
/// 2个token 就是有效期不一样
/// </summary>
/// <param name="userInfo"></param>
/// <returns></returns>
public Tuple<string, string> GetTokenWithRefresh(UserBasicInfo userInfo)
{
string token = this.IssueToken(userInfo, 60);//1分钟
string refreshToken = this.IssueToken(userInfo, 60 * 60 * 24);//24小时
TokenCache.Add(refreshToken, userInfo);
return Tuple.Create(token, refreshToken);
}
/**
* Claims (Payload)
Claims 部分包含了一些跟这个 token 有关的重要信息。 JWT 标准规定了一些字段,下面节选一些字段:
iss: The issuer of the tokentoken 是给谁的
sub: The subject of the tokentoken 主题
exp: Expiration Time。 token 过期时间,Unix 时间戳格式
iat: Issued At。 token 创建时间, Unix 时间戳格式
jti: JWT ID。针对当前 token 的唯一标识
除了规定的字段外,可以包含其他任何 JSON 兼容的字段。
* */
private string IssueToken(UserBasicInfo user, int second = 600)
{
var claims = new[]
{
new Claim(Microsoft.IdentityModel.JsonWebTokens.JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim("id", user.Id.ToString()),
new Claim("name", user.UserName),
new Claim("realName", user.RealName),
new Claim("reviewerCode",user.ReviewerCode),
new Claim("userTypeEnumName",user.UserTypeEnum.ToString()),
new Claim("userTypeEnumInt",((int)user.UserTypeEnum).ToString()),
new Claim("userTypeShortName",user.UserTypeShortName),
new Claim("isAdmin",(user.UserTypeEnum==UserType.SuperAdmin).ToString())
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(this._JWTTokenOptions.SecurityKey));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(
issuer: this._JWTTokenOptions.Issuer,
audience: this._JWTTokenOptions.Audience,
claims: claims,
expires: DateTime.Now.AddSeconds(second),//10分钟有效期
notBefore: null,//立即生效 DateTime.Now.AddMilliseconds(30),//30s后有效
signingCredentials: creds);
string returnToken = new JwtSecurityTokenHandler().WriteToken(token);
return returnToken;
}
}
}
@@ -0,0 +1,56 @@
using System;
using System.Text;
namespace ZhiZhun.AuthenticationCenter.Utility
{
public class JWTTokenDeserialize
{
public static string AnalysisToken(string token)
{
string info = token.Split('.')[1];
string escapeInfo = Escape(info);
string sInfo = FromBase64(escapeInfo);
Newtonsoft.Json.JsonConvert.DeserializeObject(sInfo);
return sInfo;
}
public static string ToBase64(string content)
{
byte[] byteContent = System.Text.Encoding.Default.GetBytes(content);
return Convert.ToBase64String(byteContent);
}
public static string FromBase64(string result)
{
byte[] byteResult = Convert.FromBase64String(result);
return System.Text.Encoding.Default.GetString(byteResult);
}
public static string Escape(string str)
{
StringBuilder sb = new StringBuilder();
foreach (char c in str)
{
sb.Append((Char.IsLetterOrDigit(c)
|| c == '-' || c == '_' || c == '\\'
|| c == '/' || c == '.') ? c.ToString() : Uri.HexEscape(c));
}
return sb.ToString();
}
public static string UnEscape(string str)
{
StringBuilder sb = new StringBuilder();
int len = str.Length;
int i = 0;
while (i != len)
{
if (Uri.IsHexEncoding(str, i))
sb.Append(Uri.HexUnescape(str, ref i));
else
sb.Append(str[i++]);
}
return sb.ToString();
}
}
}
@@ -0,0 +1,21 @@
namespace ZhiZhun.AuthenticationCenter.Utility
{
public class JWTTokenOptions
{
public string Audience
{
get;
set;
}
public string SecurityKey
{
get;
set;
}
public string Issuer
{
get;
set;
}
}
}
@@ -0,0 +1,114 @@
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.IO;
using System.Security.Claims;
using System.Security.Cryptography;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using ZhiZhun.AuthenticationCenter.User;
using ZhiZhun.AuthenticationCenter.Utility.RSA;
namespace ZhiZhun.AuthenticationCenter.Utility
{
public class JWTRSService : IJWTService
{
private static Dictionary<string, UserBasicInfo> TokenCache = new Dictionary<string, UserBasicInfo>();
#region Option注入
private readonly JWTTokenOptions _JWTTokenOptions;
public JWTRSService(IOptionsMonitor<JWTTokenOptions> jwtTokenOptions)
{
this._JWTTokenOptions = jwtTokenOptions.CurrentValue;
}
#endregion
public string GetToken(UserBasicInfo userModel)
{
return this.IssueToken(userModel);
}
private string IssueToken(UserBasicInfo user, int second = 600*6)
{
var claims = new[]
{
//new Claim(ClaimTypes.Name, userModel.Name),
//new Claim("EMail", userModel.EMail),
//new Claim("Account", userModel.Account),
//new Claim("Age", userModel.Age.ToString()),
//new Claim("Id", userModel.Id.ToString()),
//new Claim("Mobile", userModel.Mobile),
//new Claim("Sex", userModel.Sex.ToString())//各种信息拼装
//new Claim(ClaimTypes.Role,userModel.Role),
//new Claim("Role", userModel.Role),//这个不能角色授权
new Claim(Microsoft.IdentityModel.JsonWebTokens.JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim("id", user.Id.ToString()),
new Claim("name", user.UserName),
new Claim("realName", user.RealName),
new Claim("reviewerCode",user.ReviewerCode),
new Claim("userTypeEnumName",user.UserTypeEnum.ToString()),
new Claim("userTypeEnumInt",((int)user.UserTypeEnum).ToString()),
new Claim("userTypeShortName",user.UserTypeShortName),
new Claim("isAdmin",(user.UserTypeEnum==UserType.SuperAdmin).ToString())
};
string keyDir = Directory.GetCurrentDirectory();
if (RSAHelper.TryGetKeyParameters(keyDir, true, out RSAParameters keyParams) == false)
{
keyParams = RSAHelper.GenerateAndSaveKey(keyDir);
}
var credentials = new SigningCredentials(new RsaSecurityKey(keyParams), SecurityAlgorithms.RsaSha256Signature);
var token = new JwtSecurityToken(
issuer: this._JWTTokenOptions.Issuer,
audience: this._JWTTokenOptions.Audience,
claims: claims,
expires: DateTime.Now.AddSeconds(second),//默认10分钟有效期
notBefore: DateTime.Now.AddMilliseconds(30),
signingCredentials: credentials);
var handler = new JwtSecurityTokenHandler();
string tokenString = handler.WriteToken(token);
return tokenString;
}
/// <summary>
/// 刷新token的有效期问题上端校验
/// </summary>
/// <param name="refreshToken"></param>
/// <returns></returns>
public string GetTokenByRefresh(string refreshToken)
{
if (TokenCache.ContainsKey(refreshToken))
{
string token = this.IssueToken(TokenCache[refreshToken], 60);
return token;
}
else
{
return "";
}
}
public Tuple<string, string> GetTokenWithRefresh(UserBasicInfo userInfo)
{
string token = this.IssueToken(userInfo, 60);//1分钟
string refreshToken = this.IssueToken(userInfo, 60 * 60 * 24);//24小时
TokenCache.Add(refreshToken, userInfo);
return Tuple.Create(token, refreshToken);
}
}
}
@@ -0,0 +1,57 @@
using System.IO;
using System.Security.Cryptography;
using Newtonsoft.Json;
namespace ZhiZhun.AuthenticationCenter.Utility.RSA
{
public class RSAHelper
{
/// <summary>
/// 从本地文件中读取用来签发 Token 的 RSA Key
/// </summary>
/// <param name="filePath">存放密钥的文件夹路径</param>
/// <param name="withPrivate"></param>
/// <param name="keyParameters"></param>
/// <returns></returns>
public static bool TryGetKeyParameters(string filePath, bool withPrivate, out RSAParameters keyParameters)
{
string filename = withPrivate ? "key.json" : "key.public.json";
string fileTotalPath = Path.Combine(filePath, filename);
keyParameters = default(RSAParameters);
if (!File.Exists(fileTotalPath))
{
return false;
}
else
{
keyParameters = JsonConvert.DeserializeObject<RSAParameters>(File.ReadAllText(fileTotalPath));
return true;
}
}
/// 生成并保存 RSA 公钥与私钥
/// <param name="filePath">存放密钥的文件夹路径</param>
/// <param name="withPrivate"></param>
/// <returns></returns>
public static RSAParameters GenerateAndSaveKey(string filePath, bool withPrivate = true)
{
RSAParameters publicKeys, privateKeys;
using (var rsa = new RSACryptoServiceProvider(2048))//即时生成
{
try
{
privateKeys = rsa.ExportParameters(true);
publicKeys = rsa.ExportParameters(false);
}
finally
{
rsa.PersistKeyInCsp = false;
}
}
File.WriteAllText(Path.Combine(filePath, "key.json"), JsonConvert.SerializeObject(privateKeys));
File.WriteAllText(Path.Combine(filePath, "key.public.json"), JsonConvert.SerializeObject(publicKeys));
return withPrivate ? privateKeys : publicKeys;
}
}
}
@@ -0,0 +1,164 @@
<?xml version="1.0"?>
<doc>
<assembly>
<name>ZhiZhun.AuthenticationCenter</name>
</assembly>
<members>
<member name="M:Zhaoxi.NET6.AuthenticationCenter.Controllers.JWTController.Login(System.String,System.String)">
<summary>
数据库校验
</summary>
<param name="name"></param>
<param name="password"></param>
<returns></returns>
</member>
<member name="M:Zhaoxi.NET6.AuthenticationCenter.Controllers.JWTController.LoginWithRefresh(System.String,System.String)">
<summary>
生成Token+RefreshToken
</summary>
<param name="name"></param>
<param name="password"></param>
<returns></returns>
</member>
<member name="T:ZhiZhun.AuthenticationCenter.Utility.IJWTService">
<summary>
简单封装个注入
</summary>
</member>
<member name="M:ZhiZhun.AuthenticationCenter.Utility.IJWTService.GetToken(ZhiZhun.AuthenticationCenter.Utility.UserBasicInfo)">
<summary>
用户信息
</summary>
<param name="userInfo"></param>
<returns></returns>
</member>
<member name="M:ZhiZhun.AuthenticationCenter.Utility.IJWTService.GetTokenWithRefresh(ZhiZhun.AuthenticationCenter.Utility.UserBasicInfo)">
<summary>
获取Token+RefreshToken
</summary>
<param name="userInfo"></param>
<returns>Token+RefreshToken</returns>
</member>
<member name="M:ZhiZhun.AuthenticationCenter.Utility.IJWTService.GetTokenByRefresh(System.String)">
<summary>
基于refreshToken获取Token
</summary>
<param name="refreshToken"></param>
<returns></returns>
</member>
<member name="T:ZhiZhun.AuthenticationCenter.Utility.JWTHSService">
<summary>
对称可逆加密
</summary>
</member>
<member name="M:ZhiZhun.AuthenticationCenter.Utility.JWTHSService.GetTokenByRefresh(System.String)">
<summary>
刷新token的有效期问题上端校验
</summary>
<param name="refreshToken"></param>
<returns></returns>
</member>
<member name="M:ZhiZhun.AuthenticationCenter.Utility.JWTHSService.GetTokenWithRefresh(ZhiZhun.AuthenticationCenter.Utility.UserBasicInfo)">
<summary>
2个token 就是有效期不一样
</summary>
<param name="userInfo"></param>
<returns></returns>
</member>
<member name="M:ZhiZhun.AuthenticationCenter.Utility.JWTRSService.GetTokenByRefresh(System.String)">
<summary>
刷新token的有效期问题上端校验
</summary>
<param name="refreshToken"></param>
<returns></returns>
</member>
<member name="M:ZhiZhun.AuthenticationCenter.Utility.RSA.RSAHelper.TryGetKeyParameters(System.String,System.Boolean,System.Security.Cryptography.RSAParameters@)">
<summary>
从本地文件中读取用来签发 Token 的 RSA Key
</summary>
<param name="filePath">存放密钥的文件夹路径</param>
<param name="withPrivate"></param>
<param name="keyParameters"></param>
<returns></returns>
</member>
<member name="M:ZhiZhun.AuthenticationCenter.Utility.RSA.RSAHelper.GenerateAndSaveKey(System.String,System.Boolean)">
<summary>
生成并保存 RSA 公钥与私钥
</summary>
<param name="filePath">存放密钥的文件夹路径</param>
<returns></returns>
</member>
<member name="T:gRPC.ZHiZHUN.AuthServer.protos.GrpcTokenReflection">
<summary>Holder for reflection information generated from Protos/GrpcToken.proto</summary>
</member>
<member name="P:gRPC.ZHiZHUN.AuthServer.protos.GrpcTokenReflection.Descriptor">
<summary>File descriptor for Protos/GrpcToken.proto</summary>
</member>
<member name="T:gRPC.ZHiZHUN.AuthServer.protos.GetTokenReuqest">
<summary>
新增用户时需要传递数据消息, 可理解为一个类
</summary>
</member>
<member name="F:gRPC.ZHiZHUN.AuthServer.protos.GetTokenReuqest.IdFieldNumber">
<summary>Field number for the "id" field.</summary>
</member>
<member name="F:gRPC.ZHiZHUN.AuthServer.protos.GetTokenReuqest.UserNameFieldNumber">
<summary>Field number for the "userName" field.</summary>
</member>
<member name="F:gRPC.ZHiZHUN.AuthServer.protos.GetTokenReuqest.RealNameFieldNumber">
<summary>Field number for the "realName" field.</summary>
</member>
<member name="F:gRPC.ZHiZHUN.AuthServer.protos.GetTokenReuqest.ReviewerCodeFieldNumber">
<summary>Field number for the "reviewerCode" field.</summary>
</member>
<member name="F:gRPC.ZHiZHUN.AuthServer.protos.GetTokenReuqest.UserTypeEnumIntFieldNumber">
<summary>Field number for the "userTypeEnumInt" field.</summary>
</member>
<member name="F:gRPC.ZHiZHUN.AuthServer.protos.GetTokenReuqest.UserTypeShortNameFieldNumber">
<summary>Field number for the "userTypeShortName" field.</summary>
</member>
<member name="F:gRPC.ZHiZHUN.AuthServer.protos.GetTokenReuqest.IsAdminFieldNumber">
<summary>Field number for the "isAdmin" field.</summary>
</member>
<member name="T:gRPC.ZHiZHUN.AuthServer.protos.GetTokenResponse">
<summary>
新增时返回的消息格式
</summary>
</member>
<member name="F:gRPC.ZHiZHUN.AuthServer.protos.GetTokenResponse.CodeFieldNumber">
<summary>Field number for the "code" field.</summary>
</member>
<member name="F:gRPC.ZHiZHUN.AuthServer.protos.GetTokenResponse.TokenFieldNumber">
<summary>Field number for the "token" field.</summary>
</member>
<member name="T:gRPC.ZHiZHUN.AuthServer.protos.TokenGrpcService">
<summary>
service 用标识定义服务的,里面写对应的方法
</summary>
</member>
<member name="P:gRPC.ZHiZHUN.AuthServer.protos.TokenGrpcService.Descriptor">
<summary>Service descriptor</summary>
</member>
<member name="T:gRPC.ZHiZHUN.AuthServer.protos.TokenGrpcService.TokenGrpcServiceBase">
<summary>Base class for server-side implementations of TokenGrpcService</summary>
</member>
<member name="M:gRPC.ZHiZHUN.AuthServer.protos.TokenGrpcService.TokenGrpcServiceBase.GetUserToken(gRPC.ZHiZHUN.AuthServer.protos.GetTokenReuqest,Grpc.Core.ServerCallContext)">
<summary>
获取token
</summary>
<param name="request">The request received from the client.</param>
<param name="context">The context of the server-side call handler being invoked.</param>
<returns>The response to send back to the client (wrapped by a task).</returns>
</member>
<member name="M:gRPC.ZHiZHUN.AuthServer.protos.TokenGrpcService.BindService(gRPC.ZHiZHUN.AuthServer.protos.TokenGrpcService.TokenGrpcServiceBase)">
<summary>Creates service definition that can be registered with a server</summary>
<param name="serviceImpl">An object implementing the server-side handling logic.</param>
</member>
<member name="M:gRPC.ZHiZHUN.AuthServer.protos.TokenGrpcService.BindService(Grpc.Core.ServiceBinderBase,gRPC.ZHiZHUN.AuthServer.protos.TokenGrpcService.TokenGrpcServiceBase)">
<summary>Register service method with a service binder with or without implementation. Useful when customizing the service binding logic.
Note: this method is part of an experimental API that can change or be removed without any prior notice.</summary>
<param name="serviceBinder">Service methods will be bound by calling <c>AddMethod</c> on this object.</param>
<param name="serviceImpl">An object implementing the server-side handling logic.</param>
</member>
</members>
</doc>
@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}
@@ -0,0 +1,16 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ApplicationUrl": "http://localhost:7000",
"AllowedHosts": "*",
"JWTTokenOptions": {
"Audience": "IRaCIS",
"Issuer": "ZhiZhun",
"SecurityKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDI2a2EJ7m872v0afyoSDJT2o1+SitIeJSWtLJU8/Wz2m7gStexajkeD+Lka6DSTy8gt9UwfgVQo6uKjVLG5Ex7PiGOODVqAEghBuS7JzIYU5RvI543nNDAPfnJsas96mSA7L/mD7RTE2drj6hf3oZjJpMPZUQI/B1Qjb5H3K3PNwIDAQAB"
}
}
+1
View File
@@ -0,0 +1 @@
{"D":"bmUaN4NbU6fINHpR/DhZEStGnIMF5zJC393MY7TWYYIqPMJLacer7cky58yvXr1Ar4Q7RGkppPO/yzOUD72yzkZfMpVKdfvIusXfoMz2+u2j4IwIgWRAJ+bI/dB91glMMFsMBzLvasKYCKw0UeoayhIQ+WLWqTWldnTafZqtcgne7MuHTiLNBKh1uynZ/A0y3U4BVjy6FW/WZS6U5ajoDiicWxAjW9YfJ1OQbtdX0wJAos+MrES7wHdCSwuvUj7PubAoXXJEbMy5ilO/Uc/mmJoI6ZzqzL9bslBa/WixVgQzHqd46AoJIaXbni+Ei2wIwqdlZCg6J5XW5RDAx1Xk1Q==","DP":"YinAjBjQ9hQRYwmOdx+8EKF14WxMgSG3y8By5AhR2UZ22WRFjwjsD4g0abGyP6HkrwHJ+40R1P4t1OXW7yGqlzHisDeGFbxnlJLk6y9G1YLVAfdCTQgclgodztml63uB/saNhjN5TP8HfGUi6MRQr8GGmV78RpyjtvZmEobdwYs=","DQ":"drfBawNB1IwWN233uCSELtWapNQ6cjx54kY4ktKuF5RiwwNli6ydDUrbwOw7gKUPDr+hf7Mb2N+Y3M++wtw4ocEtotG0xMwwtkHRDCQC7EWV4hiN3fnVOWnV09j3GNMd9pQdp0NM2K6ZwZg82uFRtdC8Wx1B7y3rgmGqTvvD3ms=","Exponent":"AQAB","InverseQ":"j8vUuCnKnHd6QAkRzS+KDNSyoK4QDviHSayJMhV5IeqdgPH2/rOWmRrJbxMze3cnCz1V0O9OO3KK+jzY1W1EhNx5gcgr1VO748YcSCyEOg4Anj90cIPtFrCLad5qLm3pE3ZIztM+QjPlOXEehggeLQOjs7X3ehx0HO90xMrw/9Q=","Modulus":"uPdYYOZKfIqyUkjizqJ9Xn1U4M/GKJDWQ749TviZMJ/6wdJAwTkJOy3PxXXpjCyUViK4ATu1ZzAdoMTc5VC1IkG01SeEj2ynqx4q6YJnXjC5i+GqSRWP6ijbx0eDRcgVKeNm1xGM927UD1ezSFetxbD/erhrd0tNZ/QEIFATdLPd/D60RoiF8hYCc2lC61z1pKs7ZyAEckV8YaMSZAGOO/sGw1aka55aVpZ6kQmQ7sD6f27N9hOCzV6t+jxEBdANNu/wEb2Dhbvz1ap/lMrk0h+vQaTwFvudJRFifn2uvNl25NFjxz0ag+JRVnnsoXBI3PtW+1xBtvHxPCGU+tYSHQ==","P":"9Bos1g9+XzjUIn3/wQny0AUxJjl26swq/Ka1tLZmQpRdmSAN3TrxTs70s8J0XI1Gz4Y9p7HguRngCJVkdP7cXpNVaXszGH4YKEbiZ1WbAaNqa2A8CEyi0dGqPSumfbnw43UPhRNGyXsukh3uKj8ODmDJ/eXZBoHahXcHp04g7s8=","Q":"wftKXmCmnD7mKp/NYvoCQVtGOwgr5wzFuabNVcvvwGTcMjTjzVX8F97RLqM7RKLBLL12gGi/mxMdPcf4grweI3Xm6pUIACjIH4VL22VoQv6+XZjrsALhPMaLmS5mtSPHkCOQvAMdi4OOAgRRSIOP4+6grL/KkU414kb95DkuS1M="}
@@ -0,0 +1 @@
{"D":null,"DP":null,"DQ":null,"Exponent":"AQAB","InverseQ":null,"Modulus":"uPdYYOZKfIqyUkjizqJ9Xn1U4M/GKJDWQ749TviZMJ/6wdJAwTkJOy3PxXXpjCyUViK4ATu1ZzAdoMTc5VC1IkG01SeEj2ynqx4q6YJnXjC5i+GqSRWP6ijbx0eDRcgVKeNm1xGM927UD1ezSFetxbD/erhrd0tNZ/QEIFATdLPd/D60RoiF8hYCc2lC61z1pKs7ZyAEckV8YaMSZAGOO/sGw1aka55aVpZ6kQmQ7sD6f27N9hOCzV6t+jxEBdANNu/wEb2Dhbvz1ap/lMrk0h+vQaTwFvudJRFifn2uvNl25NFjxz0ag+JRVnnsoXBI3PtW+1xBtvHxPCGU+tYSHQ==","P":null,"Q":null}