jwt鉴权授权扩展 RS 非对称加密方式

  对称加密方式  就是 客户都和服务端 大家的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  上场

原文地址:https://www.cnblogs.com/jasontarry/p/14793012.html