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日

相关文章

  • Intel和NVIDIA加速卡买哪个好?Intel Xeon Phi与NVIDIA Tesla P100对比评测

    Intel和NVIDIA加速卡买哪个好? 本文将介绍Intel和NVIDIA加速卡买哪个好以及Intel Xeon Phi与NVIDIA Tesla P100对比评测的完整攻略,包括加速卡的选择、对比评测、示例说明等。 1. 加速卡的选择 在选择加速卡时,需要考虑以下几个方面: 应用场景:不同的应用场景需要不同的加速卡,例如深度学习、科学计算、图形渲染等; …

    云计算 2023年5月16日
    00
  • WebApiClient的接口输入验证方法

    WebApiClient是一款可以支持自动生成HTTP请求客户端的工具,它可以通过定义接口的方式,直接调用HTTP接口。在使用WebApiClient进行接口调用时,由于接口输入参数不符合要求可能会导致接口请求失败,因此需要对接口输入参数进行验证。 下面是WebApiClient的接口输入验证方法的完整攻略: 1. 在接口定义中使用数据注解进行验证 在Web…

    云计算 2023年5月17日
    00
  • python读取文件名及后缀详解

    Python读取文件名及后缀详解 在Python中,我们常常需要读取文件名及文件后缀来进行各种操作。本文将详细讲解如何使用Python获取文件名及文件后缀。 获取文件名 要获取文件名,我们可以使用os模块中的os.path.basename()函数。 import os # 定义文件路径 file_path = ‘C:/Users/Administrator…

    云计算 2023年5月18日
    00
  • 大数据管理系统架构Hadoop

      Hadoop 起源于Google Lab开发的Google File System (GFS)存储系统和MapReduce数据处理框架。2008年,Hadoop成了Apache上的顶级项目,发展到今天,Hadoop已经成了主流的大数据处理平台,与Spark、HBase、Hive、Zookeeper等项目一同构成了大数据分析和处理的生态系统。Hadoop是…

    2023年4月10日
    00
  • Python实现压缩和解压缩ZIP文件的方法分析

    当需要将多个文件合并成一个文件传输或存储时,压缩文件是一个非常有效的方式。ZIP是一种被广泛使用的文件格式,可以减小文件大小,并可以方便地打包和解压文件。 Python实现压缩ZIP文件 Python内置的zipfile模块提供了一种简单的方法来创建和压缩ZIP文件。下面是使用zipfile实现压缩ZIP文件的步骤。 步骤一:导入zipfile模块 使用Py…

    云计算 2023年5月18日
    00
  • 【Docker】镜像制作和管理

    一、Docker镜像说明 二、基于容器通过 docker commit 手动制作镜像 1、基于容器手动制作镜像步骤 1、下载官方系统镜像 2、基于官方基础镜像启动容器,并进入容器 3、在容器中进行配置操作   3.1、安装基础工具   3.2、配置运行环境   3.3、安装并配置服务   3.4、存放业务程序代码 4、docker commit 提交生成新镜…

    云计算 2023年4月27日
    00
  • python中如何对多变量连续赋值

    在Python中,可以使用多变量连续赋值来对多个变量进行赋值操作。这种语法结构可以省略重复的变量名,让代码更加简洁易读。 具体来说,多变量连续赋值就是通过一个等式同时给多个变量赋值。这种语法结构的形式如下: a, b, c = 1, 2, 3 上面代码中,变量a、b、c同时被赋值为1、2、3。 多变量连续赋值的规则是将等号右边的值进行打包,然后按照左边变量的…

    云计算 2023年5月18日
    00
  • 通过Java来测试JSON和Protocol Buffer的传输文件大小

    下面是通过 Java 来测试 JSON 和 Protocol Buffer 传输文件大小的攻略及示例。 一、实现过程 1.引入依赖 首先需要引入相关的依赖,在 Maven 中添加以下依赖即可: <dependency> <groupId>com.google.protobuf</groupId> <artifactI…

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