ASP.NET Core应用JWT进行用户认证及Token的刷新方案

下面是关于“ASP.NET Core应用JWT进行用户认证及Token的刷新方案”的完整攻略,包含两个示例说明。

简介

JWT(JSON Web Token)是一种用于身份验证的开放标准,它可以在客户端和服务器之间安全地传输信息。在ASP.NET Core中,我们可以使用JWT来进行用户认证,并实现Token的刷新。本文将详细讲解如何在ASP.NET Core应用中使用JWT进行用户认证及Token的刷新方案。

用户认证及Token的刷新方案

以下是在ASP.NET Core应用中使用JWT进行用户认证及Token的刷新方案的步骤:

  1. 在ASP.NET Core应用中安装Microsoft.AspNetCore.Authentication.JwtBearer NuGet包:
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer

在上面的命令中,我们使用dotnet命令来安装Microsoft.AspNetCore.Authentication.JwtBearer NuGet包。

  1. 在appsettings.json文件中添加JWT配置:
{
  "Jwt": {
    "Issuer": "YourIssuer",
    "Audience": "YourAudience",
    "Key": "YourKey",
    "ExpireMinutes": 60,
    "RefreshExpireMinutes": 1440
  }
}

在上面的代码中,我们添加了JWT的配置信息,包括Issuer、Audience、Key、ExpireMinutes和RefreshExpireMinutes等。

  1. 在Startup.cs文件中添加JWT认证服务:
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;

public void ConfigureServices(IServiceCollection services)
{
    // ...

    var jwtSettings = Configuration.GetSection("Jwt");
    var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings["Key"]));

    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =>
        {
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidateLifetime = true,
                ValidateIssuerSigningKey = true,
                ValidIssuer = jwtSettings["Issuer"],
                ValidAudience = jwtSettings["Audience"],
                IssuerSigningKey = key
            };
        });

    // ...
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    // ...

    app.UseAuthentication();
    app.UseAuthorization();

    // ...
}

在上面的代码中,我们添加了JWT认证服务,并配置了TokenValidationParameters。

  1. 在AccountController中添加登录和刷新Token的API接口:
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

[ApiController]
[Route("[controller]")]
public class AccountController : ControllerBase
{
    private readonly IConfiguration _configuration;

    public AccountController(IConfiguration configuration)
    {
        _configuration = configuration;
    }

    [AllowAnonymous]
    [HttpPost("login")]
    public IActionResult Login([FromBody] LoginModel model)
    {
        if (model == null)
        {
            return BadRequest("Invalid client request");
        }

        if (model.Username == "admin" && model.Password == "admin")
        {
            var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]));
            var signingCredentials = new SigningCredentials(secretKey, SecurityAlgorithms.HmacSha256);

            var claims = new List<Claim>
            {
                new Claim(ClaimTypes.Name, model.Username),
                new Claim(ClaimTypes.Role, "Admin")
            };

            var tokenOptions = new JwtSecurityToken(
                issuer: _configuration["Jwt:Issuer"],
                audience: _configuration["Jwt:Audience"],
                claims: claims,
                expires: DateTime.Now.AddMinutes(Convert.ToDouble(_configuration["Jwt:ExpireMinutes"])),
                signingCredentials: signingCredentials
            );

            var tokenString = new JwtSecurityTokenHandler().WriteToken(tokenOptions);
            return Ok(new { Token = tokenString });
        }
        else
        {
            return Unauthorized();
        }
    }

    [AllowAnonymous]
    [HttpPost("refresh")]
    public IActionResult Refresh([FromBody] RefreshTokenModel model)
    {
        if (model == null)
        {
            return BadRequest("Invalid client request");
        }

        var principal = GetPrincipalFromExpiredToken(model.Token);
        var username = principal.Identity.Name; //this is mapped to the Name claim by default

        var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]));
        var signingCredentials = new SigningCredentials(secretKey, SecurityAlgorithms.HmacSha256);

        var claims = new List<Claim>
        {
            new Claim(ClaimTypes.Name, username),
            new Claim(ClaimTypes.Role, "Admin")
        };

        var tokenOptions = new JwtSecurityToken(
            issuer: _configuration["Jwt:Issuer"],
            audience: _configuration["Jwt:Audience"],
            claims: claims,
            expires: DateTime.Now.AddMinutes(Convert.ToDouble(_configuration["Jwt:ExpireMinutes"])),
            signingCredentials: signingCredentials
        );

        var tokenString = new JwtSecurityTokenHandler().WriteToken(tokenOptions);
        return Ok(new { Token = tokenString });
    }

    private ClaimsPrincipal GetPrincipalFromExpiredToken(string token)
    {
        var tokenValidationParameters = new TokenValidationParameters
        {
            ValidateAudience = false,
            ValidateIssuer = false,
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"])),
            ValidateLifetime = false //here we are saying that we don't care about the token's expiration date
        };

        var tokenHandler = new JwtSecurityTokenHandler();
        SecurityToken securityToken;
        var principal = tokenHandler.ValidateToken(token, tokenValidationParameters, out securityToken);
        var jwtSecurityToken = securityToken as JwtSecurityToken;
        if (jwtSecurityToken == null || !jwtSecurityToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256, StringComparison.InvariantCultureIgnoreCase))
        {
            throw new SecurityTokenException("Invalid token");
        }

        return principal;
    }
}

public class LoginModel
{
    public string Username { get; set; }
    public string Password { get; set; }
}

public class RefreshTokenModel
{
    public string Token { get; set; }
}

在上面的代码中,我们添加了Login和Refresh API接口,用于用户登录和Token的刷新。

  1. 在Startup.cs文件中添加Swagger UI:
using Microsoft.OpenApi.Models;

public void ConfigureServices(IServiceCollection services)
{
    // ...

    services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
    });

    // ...
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    // ...

    app.UseSwagger();
    app.UseSwaggerUI(c =>
    {
        c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
    });

    // ...
}

在上面的代码中,我们添加了Swagger UI,用于测试API接口。

  1. 启动应用程序,并使用Postman等工具测试API接口。

示例说明

以下是两个示例说明,演示如何在ASP.NET Core应用中使用JWT进行用户认证及Token的刷新:

示例1:用户登录

使用Postman向"http://localhost:5000/account/login"发送POST请求,请求体中包含用户名和密码,即可获取Token。

示例2:Token刷新

使用Postman向"http://localhost:5000/account/refresh"发送POST请求,请求体中包含过期的Token,即可获取新的Token。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:ASP.NET Core应用JWT进行用户认证及Token的刷新方案 - Python技术站

(0)
上一篇 2023年5月16日
下一篇 2023年5月16日

相关文章

  • 基于阿里云函数计算实现AI推理

    场景介绍 基于阿里云函数计算建立一个TensorFlow Serverless AI推理平台。。 背景知识 函数计算 Function Compute 是事件驱动的全托管计算服务。使用函数计算,您无需采购与管理服务器等基础设施,只需编写并上传代码。函数计算为您准备好计算资源,弹性地可靠地运行任务,并提供日志查询、性能监控和报警等功能。函数计算帮助您无需管理服…

    2023年4月9日
    00
  • 云计算概念与发展

    腾讯云云计算概念与发展学习笔记 https://cloud.tencent.com/edu/learning/course-1046-872 1、云计算技术和分层架构 1.1虚拟化技术                1.2上层应用保障技术   1.3云计算产品组件           1.4云产品优势      

    云计算 2023年4月12日
    00
  • 阿里云OSS实践文件直传基于服务端

    阿里云OSS实践文件直传基于服务端 本文将介绍如何使用阿里云OSS实现文件直传基于服务端。 1. 准备作 在开始之前,需要完成以下准备工作: 注册阿里云账号并创建OSS Bucket 在服务端搭建Web服务器 在Web服务器中安装阿里OSS SDK 2. 文件直传基于服务端 阿里云OSS文件直传基于服务端,可以通过以下步骤实现: 2.1 初始化OSSClie…

    云计算 2023年5月16日
    00
  • 大话云计算:群雄华山论剑,谁能笑傲江湖

    临近2017年末,云计算群雄纷纷聚集华山开始坐而论道,当然有时也唇枪舌剑。一时间,华山之巅“Cloud Computing”、“Cloud Native”、“Big Data”、“Data Center”、“Artificial Intelligence”、“OpenStack”、“Container”……等各种词汇不绝于耳。 与此同时,最新一期的云计算英雄…

    云计算 2023年4月12日
    00
  • springboot中使用redis并且执行调试lua脚本

    Spring Boot中使用Redis并执行调试Lua脚本 在Spring Boot中,我们可以使用Redis作为缓存或数据库。同时,Redis还支持执行Lua脚本,这可以提高性能和可维护性。本文将提供一个完整攻略,包括如何在Spring Boot中使用Redis,并执行调试Lua脚本,并提供两个示例说明。 步骤1:添加Redis依赖 首先,我们需要在Spr…

    云计算 2023年5月16日
    00
  • [读书笔记]云计算时代的网络,读《腾云,云计算和大数据时代网络技术揭秘》

    我很早就有了《腾云,云计算和大数据时代网络技术揭秘》这本书的纸质版,但是一直没有细读;这次借着图灵科技的电子书阅读奖励计划“狠下心”读了起来。 正式开始分享笔记之前,先说几句题外话。 我们所处的这个时代,很多新的概念。这些概念我们感觉都明白了,但是真正让我们说出个一二三四的时候,又感觉说的不是那么清楚。 例如这个技术是什么?解决什么问题?同类的技术有哪些?这…

    2023年4月10日
    00
  • python自定义函数def的应用详解

    下面是“python自定义函数def的应用详解”的完整攻略。 什么是自定义函数? Python中的函数就像是一个独立的小程序,能够接收值并执行指定任务。Python中内置了很多函数,如print()、len()等。但是,在实际编程中,我们自己定义的函数更能符合需求。 Python中定义一个函数,通常是用def语句来实现。 语法如下: def function…

    云计算 2023年5月18日
    00
  • 阿里云飞天分布式系统使用沙箱机制的经验总结

    阿里云飞天分布式系统使用沙箱机制的经验总结 随着互联网业务逐渐规模化和复杂化,业务间的依赖性与互动性大大增强,以往的单一进程和单机数据库的简单结构已经无法满足实际需求。 阿里云飞天分布式系统是一个可靠、高可用、高稳定性的分布式服务框架,目前得到广泛应用。如何保证并发服务的稳定性和安全性,是分布式系统架构最基本的要求之一。本文将会分享飞天分布式系统如何使用沙箱…

    云计算 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部