zoukankan      html  css  js  c++  java
  • .net core3.1中实现简单的jwt认证

    1.创建项目

    使用visual studio创建一个名为JwtDemo的空项目,创建后如图

    2.添加依赖项

    • 在nuget包管理器中搜索 Microsoft.AspNetCore.Authentication.JwtBearer、System.IdentityModel.Tokens.Jwt
    • 在nuget包管理控制台安装
    Install-Package Microsoft.AspNetCore.Authentication.JwtBearer -Version 3.1.7
    Install-Package System.IdentityModel.Tokens.Jwt -Version 6.7.1
    

    3.编写代码

    创建一个接口(IJwtAuthenticationHandler),声明一个用于创建token的方法(Authenticate)

    namespace JwtDemo
    {
        public interface IJwtAuthenticationHandler
        {
            string Authenticate(string username, string password);
        }
    }
    

    创建一个类,继承接口(IJwtAuthenticationHandler),并实现方法,这里简单起见就将用户硬编码在代码中

    using System;
    using System.Collections.Generic;
    using System.IdentityModel.Tokens.Jwt;
    using System.Linq;
    using System.Security.Claims;
    using System.Text;
    
    using Microsoft.IdentityModel.Tokens;
    
    namespace JwtDemo
    {
        public class JwtAuthenticationHandler: IJwtAuthenticationHandler
        {
            private readonly IDictionary<string, string> users = new Dictionary<string, string>()
            {
                {"user1","password1"},
                {"user2","password2"},
            };
    
            private readonly string _token;   //声明一个加密的密钥,由外部传入
    
            public JwtAuthenticationHandler(string token)
            {
                _token = token;
            }
    
            public string Authenticate(string username, string password)
            {
                //如果用户名密码错误则返回null
                if (!users.Any(t => t.Key == username && t.Value == password))
                {
                    return null;
                }
                var tokenKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_token));
                var tokenHandler = new JwtSecurityTokenHandler();
                var tokenDescriptor = new SecurityTokenDescriptor()
                {
                    SigningCredentials = new SigningCredentials(tokenKey, SecurityAlgorithms.HmacSha256),
                    Expires = DateTime.Now.AddMinutes(10), 
                    Subject = new ClaimsIdentity(new Claim[]
                    {
                        new Claim(ClaimTypes.Name,username),
                    })
                };
    
                var token = tokenHandler.CreateJwtSecurityToken(tokenDescriptor);
                return tokenHandler.WriteToken(token);
            }
        }
    }
    

    修改Startup类

    using System.Text;
    
    using Microsoft.AspNetCore.Authentication.JwtBearer;
    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Hosting;
    using Microsoft.IdentityModel.Tokens;
    
    namespace JwtDemo
    {
        public class Startup
        {
            public void ConfigureServices(IServiceCollection services)
            {
                services.AddControllers();
                string tokenSecretKey = "this is a test token secret key"; //加密的密钥
                services.AddAuthentication(config =>
                {
                    //认证方案设置为Jwt
                    config.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                    config.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                }).AddJwtBearer(config=>
                {
                    config.RequireHttpsMetadata = false;
                    config.SaveToken = true;  //保存token
                    config.TokenValidationParameters = new TokenValidationParameters()
                    {
                        ValidateIssuer = false,//不验证签发人
                        ValidateAudience = false,  //不验证听众
                        ValidateIssuerSigningKey = true, //验证签发者密钥
                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(tokenSecretKey)) //签发者密钥
                    };
                });
                //将生成token的类注册为单例
                services.AddSingleton<IJwtAuthenticationHandler>(new JwtAuthenticationHandler(tokenSecretKey));
            }
            public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
    
                app.UseRouting();
                app.UseAuthentication();
                app.UseAuthorization();
                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapControllers();
                });
            }
        }
    }
    

    创建一个控制器(UserController),包含一个认证方法和一个获取用户列表(加了权限认证)的方法

    using System.Collections.Generic;
    
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Mvc;
    
    namespace JwtDemo.Controllers
    {
        [ApiController]
        public class UserController: Controller
        {
            private readonly IJwtAuthenticationHandler _jwtAuthenticationHandler;
            //构造函数注入生成token的类
            public UserController(IJwtAuthenticationHandler jwtAuthenticationHandler)
            {
                _jwtAuthenticationHandler = jwtAuthenticationHandler;
            }
    
            [AllowAnonymous]  //表示可以匿名访问
            [Route("user/authenticate")]
            [HttpPost]
            public IActionResult Authenticate([FromBody] LoginViewModel loginViewModel)
            {
                var token = _jwtAuthenticationHandler.Authenticate(loginViewModel.UserName,loginViewModel.Password);
                if (token == null)
                {
                    return Unauthorized();
                }
                return Ok(token);
            }
    
            [Authorize]   //表示需要认证授权访问
            [Route("user/list")]
            [HttpGet]
            public List<object> List()
            {
                return new List<object>()
                {
                    "user1","user2","user3","user..."
                };
            }
        }
    }
    

    LoginViewModel类

    namespace JwtDemo.Controllers
    {
        public class LoginViewModel
        {
            public string UserName { get; set; }
            public string Password { get; set; }
        }
    }
    

    完成后的项目结构

    4.测试接口

    运行项目,我们直接请求用户列表的接口,返回401,表示未授权

    我们请求认证接口进行认证,输入正确的用户名和密码,会返回一个token

    使用上面的token再次请求用户列表接口,将Header中加入Authorization:Bearer token,可以正常返回数据,表示已经成功

  • 相关阅读:
    LeetCode: Reverse Words in a String && Rotate Array
    LeetCode: Maximum Product Subarray && Maximum Subarray &子序列相关
    =new、=null、.clear()、system.gc()的区别
    对象转字符串的效率问题
    Java遍历Map对象的四种方式
    JDK升级
    eclipse的任务列表
    统一修改数据库表名字段大小写
    get传数组
    vue编辑回显问题
  • 原文地址:https://www.cnblogs.com/xiaoqingtian/p/13627947.html
Copyright © 2011-2022 走看看