asp.net基于JWT的web api身份验证及跨域调用实践

ASP.NET基于JWT的Web API身份验证及跨域调用实践

本文将详细讲解 ASP.NET 基于 JWT 的 Web API 身份验证及跨域调用实践,帮助读者理解如何构建一个基于 JWT 的 API 并使用跨域调用这个 API。

什么是JWT

JWT (JSON Web Token)是一个开放标准(RFC 7519),用于在各方之间安全地传输信息。它可以通过数字签名验证消息的完整性,同时也可以使用加密方式保护消息的保密性,因此适用于身份验证和信息交换。

JWT 三部分

JWT 由三部分组成:Header、Payload 和 Signature。每个部分的内容都是根据 Base64Url 算法将一些 JSON 序列化后的数据编码而成。这三部分的具体内容如下:

Header

Header 包含了两个属性,分别为 algtyp,通常情况下 alg 的值为 HS256,表示使用 HS256 算法进行签名;typ 的值通常为 JWT,用于说明此为 JWT。

示例:

{
  "alg": "HS256",
  "typ": "JWT"
}

Payload

Payload(负载)部分是 JWT 的主体,包含了具体的信息。Payload 是由一些声明组成的,每个声明包含有关实体(一般是用户)及其元数据的信息。同样也根据 Base64Url 算法编码。

常见的声明有:

  • iss(Issuer):JWT 的签发者。
  • sub(Subject):JWT 的主题。
  • exp(Expiration Time):JWT 的过期时间。
  • nbf(Not Before):在此时间之前,该 JWT 无法使用。
  • iat(Issued At):JWT 的签发时间。

示例:

{
  "sub": "1234567890",
  "name": "Alice",
  "admin": true,
  "exp": 1516239022
}

Signature

Signature 主要用于验证接收方是否能够信任该 JWT。Signature 是由 Header 和 Payload 使用相应的密钥签名后生成的,例如令牌生成密钥为 secret,则用 HS256 算法生成 Signature 的过程如下:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

示例:

HMACSHA256(
  eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJzdWIiOiAiMTIzNDU2Nzg5MCIsICJuYW1lIjogIkJpdGFfTWlsbHkiLCAiYWRtaW4iOiB0cnVlLCAiZXhwIjogMTUxNjIzOTAyMn0wXuzT4BPUVUGkrzWSzBx3jI3eaBcd7rxUVkcwk
  ,
  secret)

JWT 特点

  • JWT 可以被轻松地在 HTTP 和 HTML 环境中传输;
  • 由于 JWT 能够自包含,使用它的应用可以避免查询已授权的数据库;
  • 由于签名能够确保消息完整性,自包含的 JWT 可以安全地使用跨域脚本;
  • 由于 JSON 是几乎所有编程语言中的第一公民,因此使用 JWT 消息非常适合跨语言的应用程序集成。

如何使用JWT

1. 生成JWT令牌

首先需要引入 System.IdentityModel.Tokens.JwtSystem.Security.Cryptography 两个命名空间的依赖。

using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Security.Cryptography;

生成 JWT 的过程需要以下步骤:

  • 要创建 JWT,需要使用JwtSecurityToken类。这个类有许多属性可以用来设置 JWT 的声明(payload)。
  • 对于加密(和访问 JWT payload)的密钥,需要使用SymmetricSecurityKey类,它可以使用任何长度的字节流。
  • 创建 JWT 需要一个 JSON 转换器,可使用JsonSerializer类。

示例:

public string GenerateJwtToken(string username, int userId, string secret)
{
    var tokenHandler = new JwtSecurityTokenHandler();
    var key = Encoding.ASCII.GetBytes(secret);
    var tokenDescriptor = new SecurityTokenDescriptor
    {
        Subject = new ClaimsIdentity(new[]
        {
            new Claim(ClaimTypes.Name, username),
            new Claim(ClaimTypes.NameIdentifier, userId.ToString())
        }),
        Expires = DateTime.Now.AddDays(7),
        SigningCredentials = new SigningCredentials(
            new SymmetricSecurityKey(key),
            SecurityAlgorithms.HmacSha256Signature),
    };
    var token = tokenHandler.CreateToken(tokenDescriptor);
    return tokenHandler.WriteToken(token);
}

2. 验证JWT令牌

首先需要引入 Microsoft.IdentityModel.TokensSystem.IdentityModel.Tokens.Jwt 两个命名空间的依赖。

using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;

JWT 是否有效可以通过以下几个步骤进行验证:

  • 解密 JWT 令牌中的 Signature 部分;
  • 使用 Header 和 Payload 中的数据进行签名;
  • 比较本地签名与解密的 Signature 是否匹配。

示例:

public bool ValidateJwtToken(string token, string secret)
{
    var tokenHandler = new JwtSecurityTokenHandler();
    var key = Encoding.ASCII.GetBytes(secret);
    tokenHandler.ValidateToken(token, new TokenValidationParameters
    {
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new SymmetricSecurityKey(key),
        ValidateIssuer = false,
        ValidateAudience = false,
        ClockSkew = TimeSpan.Zero
    }, out SecurityToken validatedToken);
    return validatedToken != null;
}

3. 使用JWT实现身份验证

在 JWT 中发送身份验证信息是最常见的用例。Web 应用程序可以执行以下操作:

  • 一个用户自行进行身份验证,并获得一个带有所需声明的 JWT 令牌;
  • Web 应用程序存储公钥,每次收到 JWT 后进行验证。

在 Web API 的请求中,需要在 Headers 中加入 Authorization: Bearer <your_jwt_token> 作为身份验证信息。

示例:

[Authorize]
public class HomeController : Controller
{
    public IActionResult Index()
    {
        return Ok();
    }
}

4. 使用JWT实现跨域调用

基于 CORS 机制,跨域调用需要服务端设置 Access-Control-Allow-Origin,这个需要服务端配置。同时使用 JWT 时,前端需要在请求中添加 Authorization 的 Header,在后端通过 GetOwinContext().Authentication.User即可获得反序列化后的 ClaimsPrincipal 对象。

示例:

前端代码:

fetch('https://localhost:12345/api/values', {
    headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer <your_jwt_token_here>'
    }
}).then(response => {
    console.log(response);
}).catch(error => {
    console.log(error);
});

后端代码:

[Authorize]
[Route("api/[controller]")]
public class ValuesController : Controller
{
    // GET api/values
    [HttpGet]
    public IActionResult Get()
    {
        var username = User.Claims.SingleOrDefault(c => c.Type == ClaimTypes.Name)?.Value;
        var userId = User.Claims.SingleOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value;
        var result = new
        {
            username = username,
            userId = userId
        };
        return Ok(result);
    }
}

总结

在本文中,我们了解了 JWT 的概念以及其在身份验证和信息交换方面的优势。我们还讨论了如何使用 ASP.NET Core 在 Web API 中实现 JWT 身份验证,以及如何通过 JWT 实现跨域调用。希望本文对读者有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:asp.net基于JWT的web api身份验证及跨域调用实践 - Python技术站

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

相关文章

  • 24位腾讯云专家精彩演讲,4万字《腾讯云技术实践精选集 2021》发布!(附合集下载)

    摘要 随着创新技术的发展,数字经济也迎来了新的风口。新风口下,企业该如何进行云原生改造,实现成本优化?如何对基础架构和数据库技术进行创新,化解可用性、可靠性、高并发、性能、稳定性等难题? 腾讯云近期发布的《腾讯云技术实践精选集 2021》,旨在将过往积累的成功技术和解决方案经验,向外部技术同仁赋能输出,推动产业升级,促进业务创新。 听:技术专家真知灼见 《腾…

    云计算 2023年4月11日
    00
  • 常用的电商软件哪款好?四款常用的电商软件推荐

    电商软件是电子商务网站的核心,选择一款好的电商软件可以帮助企业快速搭建电商平台,提高销售效率。以下是常用的电商软件哪款好?四款常用的电商软件推荐的详细攻略: 1. 常用的电商软件 1.1. Magento Magento是一款开源的电商软件,具有丰富的功能和灵活的扩展性。Magento支持多语言、多货币、多店铺等功能,可以满足不同企业的需求。此外,Magen…

    云计算 2023年5月16日
    00
  • 如何成为一名云计算工程师

    云时代的到来,百度,阿里、腾讯借助其产业优势以云计算为核心技术发展在行业中占尽先机。对于云计算技术人才也是高薪诚聘,奈何应聘者寥寥无几。不是薪资不诱人,而是很多人都没有相应的技术去应聘。要想成为一名云计算工程师,IT专业人员首先应该掌握云计算主要领域的技能。 首先从掌握基本概念开始,然后通过掌握完全面向云计算的特定供应商的平台或技术等重要领域来增强其专业知识…

    云计算 2023年4月11日
    00
  • 重磅 | 腾讯云服务网格开源项目 Aeraki Mesh 加入 CNCF 云原生全景图

    作者 赵化冰,腾讯云工程师,Aeraki Mesh 创始人,Istio member,Envoy contributor,目前负责 Tencent Cloud Mesh 研发工作。 摘要 近日,腾讯云开源的服务网格项目 Aeraki Mesh 正式进入 CNCF 云原生全景图,位于 Service Mesh 类别下。CNCF Landscape 在云原生实践…

    云计算 2023年4月10日
    00
  • JavaScript实现获取图片文件真实格式的示例代码

    下面是关于“JavaScript实现获取图片文件真实格式的示例代码”的完整攻略,包含两个示例说明。 简介 在JavaScript中,我们可以使用FileReader对象来读取文件内容,并使用ArrayBuffer对象来处理二进制数据。在本攻略中,我们将介绍如何使用JavaScript来获取图片文件的真实格式。 步骤 在JavaScript中获取图片文件的真实…

    云计算 2023年5月16日
    00
  • Serverless冷启动:如何让函数计算更快更强?

    摘要:借助Serverless计算,开发者仅需上传业务代码并进行简单的资源配置便可实现服务的快速构建部署,云服务商则按照函数服务调用量和实际资源使用收费,从而帮助用户实现业务的快速交付和低成本运行。 本文分享自华为云社区《Serverless冷启动:如何让函数计算更快更强?》,作者:DevAI 。 问题背景 Serverless计算也称服务器无感知计算或函数…

    云计算 2023年4月17日
    00
  • 如何使用Python程序完成描述性统计分析需求

    下面是使用Python程序完成描述性统计分析的攻略。 1. 收集数据 首先,需要收集数据。数据可以来自各种渠道,如公开数据集、企业数据、用户反馈等等。在收集数据时,需要注意数据的质量和完整性。 2. 导入数据 收集到数据后,就需要将其导入到Python环境中进行处理和分析。常用的数据导入方式有: 从文本文件中读取数据。 从数据库中读取数据。 从网络中获取数据…

    云计算 2023年5月18日
    00
  • Python集中化管理平台Ansible介绍与YAML简介

    Python集中化管理平台Ansible介绍与YAML简介 Ansible介绍 Ansible是一种基于Python开发的集中化管理平台,可以使用SSH协议进行连接管理,并支持模块化、可组合的操作方式。其具有轻量、快速、高效、简单易学特点,适用于自动化配置、应用部署、编排等场景。 具体而言,Ansible可以用于: 自动化系统配置:支持定义剧本(playbo…

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