对称加密方式 就是 客户都和服务端 大家的key 都一样
非对称加密方式 服务端有个私钥 客户 有个公钥 。 私钥产生的key 拿去公钥解密 能解密就认准token
这里介绍的是第二种 非对称加密
上图 授权服务器端 只负责产生token 方法如下
JWTRSService 实现方法如下
public class JWTRSService : IJWTService { private readonly JWTTokenOptions optionsMonitor; public JWTRSService(IOptionsMonitor<JWTTokenOptions> _optionsMonitor) { optionsMonitor = _optionsMonitor.CurrentValue; } public string GetToken(ViewModels userModel) { 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(ClaimTypes.Role,userModel.Role), //new Claim("Role", userModel.Role),//这个不能角色授权 ClaimTypes.Role 不能写字符串 new Claim("Sex", userModel.Sex.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.optionsMonitor.Issuer, audience: this.optionsMonitor.Audience, claims: claims, expires: DateTime.Now.AddMinutes(60),//5分钟有效期 signingCredentials: credentials); var handler = new JwtSecurityTokenHandler(); string tokenString = handler.WriteToken(token); return tokenString; } }
生产一2个文件
1key.json 另一个key.public.json
key.public.json 用来替换 资源服务的 key 方法读取
1 个
using JwtAuthCenter.Model;
using JwtAuthCenter.Utility;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
namespace JwtAuthCenter.Controllers
{
[ApiController]
[Route("[controller]")]
public class HomeController : ControllerBase
{
private readonly ILogger<HomeController> logger;
private IJWTService jWTService = null;
public HomeController(ILogger<HomeController> _logger, IJWTService _iJWTService)
{
logger = _logger;
jWTService = _iJWTService;
}
[Route("Index")]
public IActionResult Index()
{
return new JsonResult(new
{
msg = "Hello World!",
OK = true
}); ; ;
}
[Route("Login")]
[HttpPost]
public string Login(string name, string pwd)
{
if (name == "jason" && pwd == "123")
{
ViewModels currentUser = new ViewModels()
{
Id = 123,
Account = "cxygl83@126.com",
EMail = "53262607@qq.com",
Mobile = "150000000000",
Sex = 1,
Age = 33,
Name = "Jason",
Role = "Admin"
};
string token = this.jWTService.GetToken(currentUser);
return JsonConvert.SerializeObject(new
{
result = true,
token
});
}
else
{
return JsonConvert.SerializeObject(new
{
result = false,
token = ""
});
}
}
}
}
token 服务器 基本上 配置完了
下面 是资源服务器了
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.IdentityModel.Tokens; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; using TestJWT.Models; namespace TestJWT { 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.AddControllersWithViews(); #region jwt 校验 HS 对称加密 //JWTTokenOptions tokenOptions = new JWTTokenOptions(); //Configuration.Bind("JWTTokenOptions", tokenOptions); //Console.WriteLine($"检查这个Audience值是否为空:{tokenOptions.Audience}"); //services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(option => //{ // option.TokenValidationParameters = new TokenValidationParameters // { // ValidateIssuer = true,//是否验证Issuer // ValidateAudience = true,//是否验证Audience // ValidateLifetime = true,//是否验证失效时间 // ValidateIssuerSigningKey = true,//是否验证SecurityKey // ValidAudience = tokenOptions.Audience,// // ValidIssuer = tokenOptions.Issuer,//Issuer,这两项和前面签发jwt的设置一致 // IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(tokenOptions.SecurityKey)),//拿到SecurityKey // }; //}); #endregion #region jwt 校验 RS string path = Path.Combine(Directory.GetCurrentDirectory(), "key.public.json"); string key = File.ReadAllText(path);//this.Configuration["SecurityKey"]; Console.WriteLine($"KeyPath:{path}"); var keyParams = JsonConvert.DeserializeObject<RSAParameters>(key); var credentials = new SigningCredentials(new RsaSecurityKey(keyParams), SecurityAlgorithms.RsaSha256Signature); JWTTokenOptions tokenOptions = new JWTTokenOptions(); Configuration.Bind("JWTTokenOptions", tokenOptions); services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true,//是否验证Issuer ValidateAudience = true,//是否验证Audience ValidateLifetime = true,//是否验证失效时间 ValidateIssuerSigningKey = true,//是否验证SecurityKey ValidAudience =tokenOptions.Audience,//Audience ValidIssuer = tokenOptions.Issuer,//Issuer,这两项和前面签发jwt的设置一致 IssuerSigningKey = new RsaSecurityKey(keyParams), #region MyRegion //IssuerSigningKeyValidator = (m, n, z) => // { // Console.WriteLine("This is IssuerValidator"); // return true; // }, //IssuerValidator = (m, n, z) => // { // Console.WriteLine("This is IssuerValidator"); // return "http://localhost:5726"; // }, //AudienceValidator = (m, n, z) => //{ // Console.WriteLine("This is AudienceValidator"); // return true; // //return m != null && m.FirstOrDefault().Equals(this.Configuration["Audience"]); //},//自定义校验规则,可以新登录后将之前的无效 #endregion }; }); #endregion } // 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(); } else { app.UseExceptionHandler("/Home/Error"); } app.UseStaticFiles(); app.UseRouting(); #region JWT app.UseAuthentication();//鉴权:解析信息--就是读取token,解密token #endregion app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); } } }
资源代码 没啥 加个 特性[Authorize]
postman 上场