• JWT签名与验签


    签名Token生产

    using System;
    using System.Collections.Generic;
    using System.IdentityModel.Tokens.Jwt;
    using System.Linq;
    using System.Security.Claims;
    using System.Text;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Options;
    using Microsoft.IdentityModel.Tokens;
    
    namespace CoreTest.Controllers
    {
        public class TokenController : Controller
        {
            private ITokenHelper _tokenHelper = null;
    
            public TokenController(ITokenHelper tokenHelper)
            {
                _tokenHelper = tokenHelper;
            }
    
            public IActionResult Index(string code, string pwd)
            {
                User user = TemporaryData.GetUser(code);
                if (null != user && user.Password.Equals(pwd))
                {
                    return Ok(_tokenHelper.CreateToken(user));
                }
                return BadRequest();
            }
    
            [HttpPost]
            [Authorize]
            public IActionResult Index()
            {
                return Ok(_tokenHelper.RefreshToken(Request.HttpContext.User));
            }
           
        }
    
    
        public interface ITokenHelper
        {
            Token CreateAccessToken(User user);
            ComplexToken CreateToken(User user);
            ComplexToken CreateToken(Claim[] claims);
            Token RefreshToken(ClaimsPrincipal claimsPrincipal);
        }
    
        public class TokenHelper : ITokenHelper
        {
            private IOptions<JWTConfig> _options;
            public TokenHelper(IOptions<JWTConfig> options)
            {
                _options = options;
            }
    
            public Token CreateAccessToken(User user)
            {
                Claim[] claims = new Claim[] { new Claim(ClaimTypes.NameIdentifier, user.Code), new Claim(ClaimTypes.Name, user.Name) };
    
                return CreateToken(claims, TokenType.AccessToken);
            }
    
            public ComplexToken CreateToken(User user)
            {
                Claim[] claims = new Claim[] { new Claim(ClaimTypes.NameIdentifier, user.Code), new Claim(ClaimTypes.Name, user.Name)
                //下面两个Claim用于测试在Token中存储用户的角色信息,对应测试在FlyLolo.JWT.API的两个测试Controller的Put方法,若用不到可删除
                , new Claim(ClaimTypes.Role, "TestPutBookRole"), new Claim(ClaimTypes.Role, "TestPutStudentRole")
            };
    
                return CreateToken(claims);
            }
    
            public ComplexToken CreateToken(Claim[] claims)
            {
                return new ComplexToken { AccessToken = CreateToken(claims, TokenType.AccessToken), RefreshToken = CreateToken(claims, TokenType.RefreshToken) };
            }
    
            /// <summary>
            /// 用于创建AccessToken和RefreshToken。
            /// 这里AccessToken和RefreshToken只是过期时间不同,【实际项目】中二者的claims内容可能会不同。
            /// 因为RefreshToken只是用于刷新AccessToken,其内容可以简单一些。
            /// 而AccessToken可能会附加一些其他的Claim。
            /// </summary>
            /// <param name="claims"></param>
            /// <param name="tokenType"></param>
            /// <returns></returns>
            private Token CreateToken(Claim[] claims, TokenType tokenType)
            {
                var now = DateTime.Now;
                var expires = now.Add(TimeSpan.FromMinutes(tokenType.Equals(TokenType.AccessToken) ? _options.Value.AccessTokenExpiresMinutes : _options.Value.RefreshTokenExpiresMinutes));//设置不同的过期时间
                var token = new JwtSecurityToken(
                    issuer: _options.Value.Issuer,
                    audience: tokenType.Equals(TokenType.AccessToken) ? _options.Value.Audience : _options.Value.RefreshTokenAudience,//设置不同的接受者
                    claims: claims,
                    notBefore: now,
                    expires: expires,
                    signingCredentials: new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_options.Value.IssuerSigningKey)), SecurityAlgorithms.HmacSha256));
                return new Token { TokenContent = new JwtSecurityTokenHandler().WriteToken(token), Expires = expires };
            }
    
            public Token RefreshToken(ClaimsPrincipal claimsPrincipal)
            {
                var code = claimsPrincipal.Claims.FirstOrDefault(m => m.Type.Equals(ClaimTypes.NameIdentifier));
                if (null != code)
                {
                    return CreateAccessToken(TemporaryData.GetUser(code.Value.ToString()));
                }
                else
                {
                    return null;
                }
            }
        }
    
        public class User
        {
            public string Code { get; set; }
            public string Name { get; set; }
            public string Password { get; set; }
        }
    
        public class Token
        {
            public string TokenContent { get; set; }
    
            public DateTime Expires { get; set; }
        }
    
        public enum TokenType
        {
            AccessToken = 1,
            RefreshToken = 2
        }
    
        public class ComplexToken
        {
            public Token AccessToken { get; set; }
            public Token RefreshToken { get; set; }
        }
    
        public class JWTConfig
        {
            public string Issuer { get; set; }
            public string Audience { get; set; }
            public string IssuerSigningKey { get; set; }
            public int AccessTokenExpiresMinutes { get; set; }
            public string RefreshTokenAudience { get; set; }
            public int RefreshTokenExpiresMinutes { get; set; }
        }
    
    public static class TemporaryData
        {
            private static List<User> Users = new List<User>()
            {
                new User { Code = "001", Name = "张三", Password = "111111" },
                new User { Code = "002", Name = "李四", Password = "222222" }
            };
    
            public static User GetUser(string code)
            {
                return Users.FirstOrDefault(m => m.Code.Equals(code));
            }
        }
    }

    appsettings.json

    {
      "Logging": {
        "LogLevel": {
          "Default": "Warning"
        }
      },
      "AllowedHosts": "*",
    
      "JWT": {
        "Issuer": "FlyLolo",
        "Audience": "TestAudience",
        "IssuerSigningKey": "FlyLolo1234567890",
        "AccessTokenExpiresMinutes": "30",
        "RefreshTokenAudience": "RefreshTokenAudience",
        "RefreshTokenExpiresMinutes": "10080"
      }
    }

    Startup.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using CoreTest.Controllers;
    using Microsoft.AspNetCore.Authentication.JwtBearer;
    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.HttpsPolicy;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Logging;
    using Microsoft.Extensions.Options;
    using Microsoft.IdentityModel.Tokens;
    
    namespace CoreTest
    {
        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.Configure<Controllers.UserInfo>(Configuration.GetSection("User"));
                services.AddSingleton<ITokenHelper, TokenHelper>();
                services.Configure<JWTConfig>(Configuration.GetSection("JWT"));
                JWTConfig config = new JWTConfig();
                Configuration.GetSection("JWT").Bind(config);
    
                services.AddAuthentication(options => {
                    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                })
                .AddJwtBearer(options => {
                    options.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidIssuer = config.Issuer,
                        ValidAudience = config.RefreshTokenAudience,
                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(config.IssuerSigningKey))
                    };
                });
    
                services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
            }
    
            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IHostingEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
                else
                {
                    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                    app.UseHsts();
                }
    
                app.UseHttpsRedirection();
    
                app.UseAuthentication();
                app.UseMvc(route =>
                {
                    route.MapRoute(
                        name: "default",
                        template: "{controller=Home}/{action=Index}/{id?}"
                        );
                });
            }
        }
    }

    Token验证

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Mvc;
    
    namespace ClientTest.Controllers
    {
        [Route("api/[controller]")]
        [ApiController]
        [Authorize]
        public class BookController : ControllerBase
        {
            // GET: api/<controller>
            [HttpGet]
            [AllowAnonymous]
            public IEnumerable<string> Get()
            {
                return new string[] { "ASP", "C#" };
            }
    
            // POST api/<controller>
            [HttpPost]
            public JsonResult Post()
            {
                return new JsonResult("Create  Book ...");
            }
        }
    
    
        public class JWTConfig
        {
        public string Issuer { get; set; }
        public string Audience { get; set; }
        public string IssuerSigningKey { get; set; }
        public int AccessTokenExpiresMinutes { get; set; }
    }
    }

    appsettings.json

    {
      "Logging": {
        "LogLevel": {
          "Default": "Warning"
        }
      },
      "AllowedHosts": "*",
      "JWT": {
        "Issuer": "FlyLolo",
        "Audience": "TestAudience",
        "IssuerSigningKey": "FlyLolo1234567890",
        "AccessTokenExpiresMinutes": "30"
      }
    }

    Startup.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using ClientTest.Controllers;
    using Microsoft.AspNetCore.Authentication.JwtBearer;
    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.HttpsPolicy;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Logging;
    using Microsoft.Extensions.Options;
    using Microsoft.IdentityModel.Tokens;
    
    namespace ClientTest
    {
        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)
            {
                #region 读取配置
                JWTConfig config = new JWTConfig();
                Configuration.GetSection("JWT").Bind(config);
                #endregion
    
                #region 启用JWT认证
                services.AddAuthentication(options =>
                {
                    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                }).
                AddJwtBearer(options =>
                {
                    options.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidIssuer = config.Issuer,
                        ValidAudience = config.Audience,
                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(config.IssuerSigningKey)),
                        ClockSkew = TimeSpan.FromMinutes(1)
                    };
                });
                #endregion
    
                services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
            }
    
            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IHostingEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
                else
                {
                    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                    app.UseHsts();
                }
    
                app.UseHttpsRedirection();
                app.UseAuthentication();
                app.UseMvc();
            }
        }
    }
  • 相关阅读:
    Nginx 配置文件
    Nginx 目录结构
    Nginx 功能模块
    logrotate日志管理工具
    Nginx 编译安装
    CentOS7安装Tomcat
    springcloud如何实现服务的平滑发布
    springcloud zuul聚合微服务的swagger文档
    alibaba的springcloud孵化器项目
    springcloud灰度发布实现方案
  • 原文地址:https://www.cnblogs.com/huangzelin/p/11475191.html
Copyright © 2020-2023  润新知