zoukankan      html  css  js  c++  java
  • .net core 3.1 jwt认证

    1. 首先在Visual Studio中创建一个WebApi项目;
    2. 引入nuget包:Microsoft.AspNetCore.Authentication.JwtBearer
    3. 在appsetting.json中配置jwt参数
    "tokenConfig": {
        "secret": "D96BFA5B-F2AF-45BC-9342-5A55C3F9BBB0",
        "issuer": "test.cn",
        "audience": "test",
        "accessExpiration": 30,
        "refreshExpiration": 60
      }
    
    1. 编写对应的token对象:
    using Newtonsoft.Json;
    
    namespace JwtDemo
    {
        public class TokenManagement
        {
            [JsonProperty("secret")]
            public string Secret { get; set; }
    
            [JsonProperty("issuer")]
            public string Issuer { get; set; }
    
            [JsonProperty("audience")]
            public string Audience { get; set; }
    
            [JsonProperty("accessExpiration")]
            public int AccessExpiration { get; set; }
    
            [JsonProperty("refreshExpiration")]
            public int RefreshExpiration { get; set; }
        }
    }
    
    1. 在Startup中配置启用token认证
    using System.Text;
    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 static JwtDemo.LoginRequestDTO;
    
    namespace JwtDemo
    {
        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.AddControllers();
                services.Configure<TokenManagement>(Configuration.GetSection("tokenConfig"));
    
                var token = Configuration.GetSection("tokenConfig").Get<TokenManagement>();
    
                services.AddAuthentication(x =>
                {
                    x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                    x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                }).AddJwtBearer(x =>
                {
                    x.RequireHttpsMetadata = false;
                    x.SaveToken = true;
                    //Token Validation Parameters
                    x.TokenValidationParameters = new TokenValidationParameters
                    {
                        ValidateIssuerSigningKey = true,
                        //获取或设置要使用的Microsoft.IdentityModel.Tokens.SecurityKey用于签名验证。
                        IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.
                        GetBytes(token.Secret)),
                        //获取或设置一个System.String,它表示将使用的有效发行者检查代币的发行者。
                        ValidIssuer = token.Issuer,
                        //获取或设置一个字符串,该字符串表示将用于检查的有效受众反对令牌的观众。
                        ValidAudience = token.Audience,
                        ValidateIssuer = false,
                        ValidateAudience = false,
                    };
                });
                services.AddScoped<IAuthenticateService, TokenAuthenticationService>();
                services.AddScoped<IUserService, UserService>();
            }
    
            // 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();
                }
    
                app.UseHttpsRedirection();
    
                app.UseAuthentication();
                
                app.UseRouting();
    
                app.UseAuthorization();
    
                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapControllers();
                });
            }
        }
    }
    
    
    1. 编写认证服务接口及服务类
    using Microsoft.Extensions.Options;
    using Microsoft.IdentityModel.Tokens;
    using Newtonsoft.Json;
    using System;
    using System.ComponentModel.DataAnnotations;
    using System.IdentityModel.Tokens.Jwt;
    using System.Security.Claims;
    using System.Text;
    
    namespace JwtDemo
    {
        public interface IAuthenticateService
        {
            bool IsAuthenticated(LoginRequestDTO request, out string token);
        }
    
        public class LoginRequestDTO
        {
            [Required]
            [JsonProperty("username")]
            public string Username { get; set; }
    
    
            [Required]
            [JsonProperty("password")]
            public string Password { get; set; }
    
            /// <summary>
            /// token认证服务
            /// </summary>
            public class TokenAuthenticationService : IAuthenticateService
            {
                private readonly IUserService _userService;
                private readonly TokenManagement _tokenManagement;
                public TokenAuthenticationService(IUserService userService, IOptions<TokenManagement> tokenManagement)
                {
                    _userService = userService;
                    _tokenManagement = tokenManagement.Value;
                }
                public bool IsAuthenticated(LoginRequestDTO 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(_tokenManagement.Secret));
                    var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
                    var jwtToken = new JwtSecurityToken(_tokenManagement.Issuer, _tokenManagement.Audience, claims,
                        expires: DateTime.Now.AddMinutes(_tokenManagement.AccessExpiration),
                        signingCredentials: credentials);
                    token = new JwtSecurityTokenHandler().WriteToken(jwtToken);
                    return true;
                }
            }
    
        }
    
    }
    
    
    1. 自定义认证接口及类IUserService和UserService,模拟验证密码的过程,这个需要在Startup中配置注入服务
    namespace JwtDemo
    {
        public interface IUserService
        {
            bool IsValid(LoginRequestDTO req);
        }
    
        public class UserService : IUserService
        {
            //模拟测试,默认都是人为验证有效
            public bool IsValid(LoginRequestDTO req)
            {
                return true;
            }
        }
    }
    
    1. 添加AuthenticationController,用于根据用户名和密码获取token
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Mvc;
    
    namespace JwtDemo.Controllers
    {
        [Route("api/[controller]")]
        [ApiController]
        public class AuthenticationController : ControllerBase
        {
            private readonly IAuthenticateService _authService;
            public AuthenticationController(IAuthenticateService authService)
            {
                this._authService = authService;
            }
    
            [AllowAnonymous]
            [HttpPost, Route("requestToken")]
            public ActionResult RequestToken([FromBody] LoginRequestDTO request)
            {
                if (!ModelState.IsValid)
                {
                    return BadRequest("Invalid Request");
                }
    
                string token;
                if (_authService.IsAuthenticated(request, out token))
                {
                    return Ok(token);
                }
    
                return BadRequest("Invalid Request");
            }
    
        }
    }
    
    1. 测试:测试之前先给WeatherForecastController加上[Authorize],身份验证之后才能访问
    • 先访问https://localhost:44324/weatherforecast,结果为401,未授权,

    • 下面请求token:

    获取到token:

    带token访问被保护的webapi:

    成功获取到webapi数据:

    通过学习了解了基本的jwt认证的使用方法
    学会了在Fiddler中测试webapi
    源码:https://gitee.com/Alexander360/LearnIdentity/tree/master/LearnIdentity

  • 相关阅读:
    第3章 C++ I/O流技术
    第2章 C++模板技术
    第1章 C++编程技术
    第0章 目录
    判断鼠标移入移出方向设置
    获取数组最小值
    jquery里的宽度详解
    trigger,triggerhandler模拟事件
    表单验证 不能为负值或者字母
    arguments的用法
  • 原文地址:https://www.cnblogs.com/AlexanderZhao/p/jwtdemo.html
Copyright © 2011-2022 走看看