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

yizhihongxing

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日

相关文章

  • 详解CSS动画属性关键帧keyframes全解析

    详解CSS动画属性关键帧keyframes全解析 CSS动画是Web开发中非常重要的一部分,它可以为网页增加生动的效果和交互性。在CSS动画中,关键帧(keyframes)是非常重要的一部分,它可以定义动画的每个阶段的样式。本文将提供一个完整的攻略,包括如何使用关键帧、关键帧的语法、关键帧的属性和两个示例说明。 使用关键帧 在CSS动画中,我们可以使用关键帧…

    云计算 2023年5月16日
    00
  • 如何使用签名保证ASP.NET MVC OR WEBAPI的接口安全

    使用签名可以保证ASP.NET MVC OR WEBAPI的接口安全,以下是完整攻略的步骤: 步骤一:生成API密钥 API密钥是用来保密签名密钥的,所以必须是长而复杂的随机字符串。可以使用Guid.NewGuid().ToString()方法生成一个符合要求的API密钥。 步骤二:生成签名密钥 签名密钥也必须是随机的,并且应该远离API密钥。可以通过使用G…

    云计算 2023年5月17日
    00
  • 云计算openstack核心组件——keystone身份认证服务

    本文转载于  https://www.cnblogs.com/cloudhere/p/10811666.html 在此向原创作者表示致谢! 一、Keystone介绍:       keystone 是OpenStack的组件之一,用于为OpenStack家族中的其它组件成员提供统一的认证服务,包括身份验证、令牌的发放和校验、服务列表、用户权限的定义等等。云环…

    2023年4月9日
    00
  • asp.net(C#)跨域及跨域写Cookie问题

    下面是关于“ASP.NET(C#)跨域及跨域写Cookie问题”的完整攻略,包含两个示例说明。 简介 在ASP.NET(C#)应用程序中,我们经常需要处理跨域请求和跨域写Cookie问题。在本攻略中,我们将介绍如何在ASP.NET(C#)应用程序中处理跨域请求和跨域写Cookie问题,并提供两个示例说明。 步骤 在ASP.NET(C#)应用程序中处理跨域请求…

    云计算 2023年5月16日
    00
  • ASP.NET Core自定义中间件如何读取Request.Body与Response.Body的内容详解

    下面是关于“ASP.NET Core自定义中间件如何读取Request.Body与Response.Body的内容详解”的完整攻略,包含两个示例说明。 简介 在ASP.NET Core中,可以使用自定义中间件来处理HTTP请求和响应。在本攻略中,我们将介绍如何在自定义中间件中读取Request.Body和Response.Body的内容。 步骤 在ASP.N…

    云计算 2023年5月16日
    00
  • “云计算技能第一次在线练兵”精彩纷呈!欢迎继续关注后续直播!

    2月19日下午2点,“云计算技能第一次在线练兵”直播和大家如约见面,热烈的互动,激烈的排名······云创大数据的讲师团队带领大家共同领略了云计算练兵的魅力。 在直播间,我们首先了解到本次练兵的规则、奖励机制以及练兵平台等,对整个练兵有了更为全面的认识。同时,在直播过程中,选手的在线操作得以实况呈现,包括得分趋势、得分事件等,并得到一一解说,分析得分点与失分…

    云计算 2023年4月12日
    00
  • Asp.net Core 初探(发布和部署Linux)

    Asp.net Core 初探(发布和部署Linux) Asp.net Core是一个跨平台的开源框架,可以在Windows、Linux和macOS上运行。本文将提供一个完整的攻略,包括如何发布和部署Asp.net Core应用程序到Linux服务器上,以及如何使用例代码内容。 发布Asp.net Core应用程序 在发布Asp.net Core应用程序之前…

    云计算 2023年5月16日
    00
  • spring data jpa使用详解(推荐)

    下面是针对“spring data jpa使用详解(推荐)”进行详细讲解的攻略: 一、前言 Spring Data JPA 是基于 Hibernate 来实现 JPA 接口的实现,为我们处理项目中的数据提供了非常便捷的方式。本篇攻略将为你讲解使用 Spring Data JPA 的过程。 二、Spring Data JPA 简介 Spring Data JP…

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