.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,可以正常返回数据,表示已经成功

posted @ 2020-09-07 17:11  等一个,晴天  阅读(550)  评论(0编辑  收藏  举报