博客
关于我
ASP.NET Core - JWT认证实现
阅读量:418 次
发布时间:2019-03-06

本文共 6659 字,大约阅读时间需要 22 分钟。

一、JWT结构

 JWT介绍就太多了,这里主要关注下Jwt的结构。 

 Jwt中包含三个部分:Header(头部).Payload(负载).Signature(签名)

  • Header:描述 JWT 的元数据的JSON对象,如:

    {"alg":"HS256","typ":"JWT"}
  • Payload:一个用来存放实际需要传递的数据的JSON 对象。如:

    "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name": "admin",    "exp": 1610877510,    "iss": "cba",    "aud": "cba"}
  • Signature:对前两部分(Header、Payload)的签名,防止数据篡改。
    HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

  JWT示例:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiYWRtaW4iLCJleHAiOjE2MTA4Nzc1MTAsImlzcyI6ImNiYSIsImF1ZCI6ImNiYSJ9.O9lbZwfqRuA6vKcRCfYieA1zLkTPppdSvTc8UzwCkNw

二、ASP.NET Core 使用JTW认证

 1、添加Nuget包引用:

dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer

 2、定义一个JwtSettingDto结构,用于读取JWT配置信息

public class JwtSetting{    /// <summary>    /// 发行者    /// </summary>    public string Issuer { get; set; }    /// <summary>    /// 受众    /// </summary>    public string Audience { get; set; }    /// <summary>    /// 秘钥    /// </summary>    public string SecretKey { get; set; }    /// <summary>    /// 过期时间    /// </summary>    public int AccessExpiration { get; set; }    /// <summary>    /// 刷新时间    /// </summary>    public int RefreshExpiration { get; set; }}

 3、在appsetting.json配置文件中,添加jwt相关配置信息

  "JWTSetting": {    "Issuer": "cba",    "Audience": "cba",    "SecretKey": "123456789abcdefghi",    "AccessExpiration": 60,    "RefreshExpiration": 80  }

 4、在Startup.cs 中启用Jwt认证

public void ConfigureServices(IServiceCollection services){    services.Configure<JwtSetting>(Configuration.GetSection("JWTSetting"));    var token = Configuration.GetSection("JWTSetting").Get<JwtSetting>();    //JWT认证    services.AddAuthentication(x =>    {        x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;        x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;    }).AddJwtBearer(x =>    {        x.RequireHttpsMetadata = false;        x.SaveToken = true;        x.TokenValidationParameters = new TokenValidationParameters        {            ValidateIssuerSigningKey = true,            IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(token.SecretKey)),            ValidIssuer = token.Issuer,            ValidAudience = token.Audience,            ValidateIssuer = false,            ValidateAudience = false        };    });}// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.public void Configure(IApplicationBuilder app, IWebHostEnvironment env){    app.UseAuthentication();    app.UseAuthorization();}

 5、实现认证控制器:

  a) 添加认证Dto

public class LoginDto{    [Required]    public string Username { get; set; }    [Required]    public string Password { get; set; }}

  b) 实现用户校验服务:默认实现:当用户密码都等于admin通过校验  

public interface IUserService{    bool IsValid(LoginDto request);}public class UserService : IUserService{    //本次,固定校验admin    public bool IsValid(LoginDto request)    {        return request.Password == request.Username && request.Username == "admin";    }}

  c) 实现签发token的认证服务:  

//认证服务接口
public
interface IAuthenticateService{ bool IsAuthenticated(LoginDto request, out string token);}//认证服务public class TokenAuthenticationService : IAuthenticateService{ private readonly IUserService _userService; private readonly JwtSetting _jwtSetting; public TokenAuthenticationService(IUserService userService, IOptions<JwtSetting> jwtSetting) { _userService = userService; _jwtSetting = jwtSetting.Value; } public bool IsAuthenticated(LoginDto request, out string token) { token = string.Empty; if (!_userService.IsValid(request)) return false; var claims = new[] { new Claim(ClaimTypes.Name, request.Username) }; var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSetting.SecretKey)); var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var jwtToken = new JwtSecurityToken(_jwtSetting.Issuer, _jwtSetting.Audience, claims, expires: DateTime.Now.AddMinutes(_jwtSetting.AccessExpiration), signingCredentials: credentials); token = new JwtSecurityTokenHandler().WriteToken(jwtToken); return true; }}

  d) 添加认证控制器

[Route("api/[controller]")][ApiController]public class AuthenticationController : ControllerBase{    private IAuthenticateService _authService;    public AuthenticationController(IAuthenticateService authService)    {        _authService = authService;    }    [AllowAnonymous]    [HttpPost, Route("RequestToken")]    public ActionResult RequestToken([FromBody] LoginDto request)    {        if (!ModelState.IsValid)        {            return BadRequest("Invalid Request");        }        string token;        if (_authService.IsAuthenticated(request, out token))        {            return Ok(token);        }        return BadRequest("Invalid Request");    }}

 6、注入服务:TokenAuthenticationService 、UserService 

services.AddScoped<IUserService, UserService>();services.AddScoped<IAuthenticateService, TokenAuthenticationService>();

 7、添加测试控制器:

[Authorize][Route("api/[controller]")][ApiController]public class AuditLogController : ControllerBase{    // GET: api/<AuditLogController>    [HttpGet]    public IEnumerable<string> Get()    {        return new string[] { "value1", "value2" };    }}

     到此Jwt认证在.net core中已经实现,接下来验证下运行效果

三、验证结果

 1、请求AuditLog接口:api/AuditLog未传入认证信息时:

  

  2、获取Token:

  

 3、添加token调用接口:

  

四、Swagger UI添加认证

  在项目中通常都添加了Swagger UI来展示接口及基础测试,那么如果添加了认证后,如何在调用接口前添加认证信息呢?

  在Startup中:ConfigureServices中添加Swagger设置时,添加认证设置

//注册Swagger生成器,定义一个和多个Swagger 文档services.AddSwaggerGen(c =>{    c.SwaggerDoc("v1", new OpenApiInfo { Title = "AuditLogDemo API", Version = "v1" });    #region 启用swagger验证功能    //添加一个必须的全局安全信息,和AddSecurityDefinition方法指定的方案名称一致即可。    c.AddSecurityRequirement(new OpenApiSecurityRequirement    {        {            new OpenApiSecurityScheme            {                Reference = new OpenApiReference {                    Type = ReferenceType.SecurityScheme,                    Id = "Bearer"                }            },            new string[] { }        }    });    c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme    {        Description = "JWT授权(数据将在请求头中进行传输) 在下方输入Bearer {token} 即可,注意两者之间有空格",        Name = "Authorization",//jwt默认的参数名称        In = ParameterLocation.Header,//jwt默认存放Authorization信息的位置(请求头中)        Type = SecuritySchemeType.ApiKey,        BearerFormat = "JWT",        Scheme = "Bearer",                                      });    #endregion});

  运行效果: 添加token->调用需认证接口

   

       

其他:

  源码地址:https://github.com/cwsheng/AuditLogDemo.git

转载地址:http://ddwuz.baihongyu.com/

你可能感兴趣的文章
MangoDB4.0版本的安装与配置
查看>>
Manjaro 24.1 “Xahea” 发布!具有 KDE Plasma 6.1.5、GNOME 46 和最新的内核增强功能
查看>>
mapping文件目录生成修改
查看>>
MapReduce程序依赖的jar包
查看>>
mariadb multi-source replication(mariadb多主复制)
查看>>
MariaDB的简单使用
查看>>
MaterialForm对tab页进行隐藏
查看>>
Member var and Static var.
查看>>
memcached高速缓存学习笔记001---memcached介绍和安装以及基本使用
查看>>
memcached高速缓存学习笔记003---利用JAVA程序操作memcached crud操作
查看>>
Memcached:Node.js 高性能缓存解决方案
查看>>
memcache、redis原理对比
查看>>
memset初始化高维数组为-1/0
查看>>
Metasploit CGI网关接口渗透测试实战
查看>>
Metasploit Web服务器渗透测试实战
查看>>
MFC模态对话框和非模态对话框
查看>>
Moment.js常见用法总结
查看>>
MongoDB出现Error parsing command line: unrecognised option ‘--fork‘ 的解决方法
查看>>
mxGraph改变图形大小重置overlay位置
查看>>
MongoDB可视化客户端管理工具之NoSQLbooster4mongo
查看>>