使用 JWT 库

JWT,a JWT(JSON Web Token) implementation for .NET

该库支持生成和解析JSON Web Token

你可以直接通过Nuget获取,也可以自己下载和编译源码.

// 不要忘了 using
using JWT;
using JWT.Algorithms;
using JWT.Builder; // 自定义秘钥
// jwt 的生成和解析都需要使用
const string secret = "GQDstcKsx0NHjPOuXOYg5MbeJ1XT0uFiwDVvVBrk";

创建 JWT

// 使用 JwtBuilder 来生成 token
string token = new JwtBuilder()
.WithAlgorithm(new HMACSHA256Algorithm()) // 使用算法
.WithSecret(secret) // 使用秘钥
.AddClaim("exp", DateTimeOffset.UtcNow.AddHours(1).ToUnixTimeSeconds())
.AddClaim("claim2", "claim2-value")
.Build(); Console.WriteLine(token);

生成的 token 如下:

// 注意:是通过.符号分隔成3段,分别对应的是header.payload.signature
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1Mjg3MjA2NTEsImNsYWltMiI6ImNsYWltMi12YWx1ZSJ9.56xcZALlJuwROe3qssCbe_DDjpQShk-Ik7kWAzONWFU

生成后可以分发出去, 别人拿着 token 来请求接口的时候, 我们需要解析验证

// 使用 JwtBuilder 来解析 token
try
{
string json = new JwtBuilder()
.WithSecret(secret)
.MustVerifySignature()
.Decode(token); Console.WriteLine(json);
}
catch (TokenExpiredException)
{
Console.WriteLine("token 已过期");
}
catch (SignatureVerificationException)
{
Console.WriteLine("token 签名无效");
}

解析后得到的 json 字符串如下:

{
"exp": 1528721303,
"claim2": "claim2-value"
}

使用 Microsoft.IdentityModel.Tokens 库

  • 新建一个 ASP.NET Core API 项目
  • 新增一个控制器 AuthController

生成 JWT

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; namespace WebApplication1.Controllers
{
[ApiController]
[Route("[controller]/[action]")]
public class AuthController : Controller
{
private readonly IConfiguration _configuration; public AuthController(IConfiguration configuration)
{
_configuration = configuration;
} [HttpGet]
public IActionResult Token()
{
var claims = new[]
{
new Claim(type: ClaimTypes.Name, value: "username")
}; var issuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["IssuerSigningKey"]));
var creds = new SigningCredentials(issuerSigningKey, SecurityAlgorithms.HmacSha256);
//.NET Core’s JwtSecurityToken class takes on the heavy lifting and actually creates the token.
/**
* Claims (Payload)
Claims 部分包含了一些跟这个 token 有关的重要信息。 JWT 标准规定了一些字段,下面节选一些字段:
iss: The issuer of the token,token 是给谁的
sub: The subject of the token,token 主题
exp: Expiration Time。 token 过期时间,Unix 时间戳格式
iat: Issued At。 token 创建时间, Unix 时间戳格式
jti: JWT ID。针对当前 token 的唯一标识
除了规定的字段外,可以包含其他任何 JSON 兼容的字段。
* */
var token = new JwtSecurityToken(
issuer: "test.com", //
audience: "test.com",
claims: claims,
expires: DateTime.Now.AddMinutes(1),
signingCredentials: creds); return Ok(new
{
access_token = new JwtSecurityTokenHandler().WriteToken(token: token)
});
}
}
}

生成的 JWT 可以放到 jwt.io 里验证一下.

使用 IdentityServer4 库

IdentityServerTools 是 IdentityServer4 中的一个工具类, 封装了 JWT 生成方法, 以便使用.

按照套路, 注入 IdentityServer4 服务, 这里我们仅使用工具类来生成 JWT, 所以不需要配置其他东西.

public void ConfigureServices(IServiceCollection services)
{
services.AddIdentityServer()
.AddDeveloperSigningCredential();
// 省略其他
}

在控制器中构造函数注入使用

using IdentityServer4;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Security.Claims;
using System.Threading.Tasks; // For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 namespace WebApplication1.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class AuthController : ControllerBase
{
private readonly IdentityServerTools _identityServerTools; public AuthController(IdentityServerTools identityServerTools)
{
_identityServerTools = identityServerTools;
} [HttpGet]
public async Task<IActionResult> TokenAsync()
{
// 完整的场景, 应该验证用户密码
Claim[] claims = new Claim[]
{
new Claim(type: ClaimTypes.NameIdentifier, value: Guid.NewGuid().ToString("N")),
new Claim(type: ClaimTypes.Name, value: "admin"),
new Claim(type: ClaimTypes.Gender, value: "man"),
new Claim(type: ClaimTypes.Email, value: "xxx@xxx.com"),
new Claim(type: "custom", value: "value"),
}; // 可以按自己需求, 返回指定结构的数据
return Ok(value: await _identityServerTools.IssueJwtAsync(lifetime: 3600, claims: claims));
}
}
}

这个时候访问 /api/auth 应该就能看到一段老长老长的 JWT 了, 可以扔到 jwt.io 里验证下.

身份认证

上面介绍了几种不同库生成 JWT 的方法, 当别人拿着我们分发出去的 JWT 来访问我们的接口时, 需要对其进行身份认证

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens; namespace WebApplication1
{
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.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false, // 是否验证 Issuer
ValidIssuer = "test.com",
ValidateAudience = false, // 是否验证 Audience
ValidAudience = "",
ValidateIssuerSigningKey = true, // 是否验证签名秘钥
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["IssuerSigningKey"])),
ValidateLifetime = true, // 是否验证失效时间
};
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
} // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseAuthentication(); // 使用身份验证
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
} app.UseMvc();
}
}
}

参考

.NET & JWT的更多相关文章

  1. 看图理解JWT如何用于单点登录

    单点登录是我比较喜欢的一个技术解决方案,一方面他能够提高产品使用的便利性,另一方面他分离了各个应用都需要的登录服务,对性能以及工作量都有好处.自从上次研究过JWT如何应用于会话管理,加之以前的项目中也 ...

  2. JWT实现token-based会话管理

    上文<3种web会话管理的方式>介绍了3种会话管理的方式,其中token-based的方式有必要从实现层面了解一下.本文主要介绍这方面的内容.上文提到token-based的实现目前有一个 ...

  3. 用JWT来保护我们的ASP.NET Core Web API

    在上一篇博客中,自己动手写了一个Middleware来处理API的授权验证,现在就采用另外一种方式来处理这个授权验证的问题,毕竟现在也 有不少开源的东西可以用,今天用的是JWT. 什么是JWT呢?JW ...

  4. Laravel-lumen 配置JWT

    具体步骤参照: [ JWT & Lumen ] 第一步 在项目根目录 执行命令 composer require tymon/jwt-auth第二步 在 bootstrap/app.php 的 ...

  5. .net core Jwt 添加

    Jwt 已经成为跨平台身份验证通用方案,如不了解请关注:https://jwt.io/. 为了和微软其他验证模块有个比较好的衔接,项目中采用了微软开发的jwt组件: System.IdentityMo ...

  6. 多说评论系统API调用和本地身份说明(JWT)

    多说评论系统是一个非常好用的第三方评论插件,聚合了大多数的SNS平台账号登录和分享功能,UI也很不错. 作为网站快速接入评论系统,多说是一个比较好的选择,其也提供了一些实用的API去满足定制化需求. ...

  7. 【JWT】JWT+HA256加密 Token验证

    目录 Token验证 传统的Token验证 JWT+HA256验证 回到顶部 Token验证 最近了解下基于 Token 的身份验证,跟大伙分享下.很多大型网站也都在用,比如 Facebook,Twi ...

  8. 基于Token的身份验证——JWT

    初次了解JWT,很基础,高手勿喷. 基于Token的身份验证用来替代传统的cookie+session身份验证方法中的session. JWT是啥? JWT就是一个字符串,经过加密处理与校验处理的字符 ...

  9. jwt refresh token

    $app->post('auth/refresh-token', ['middleware' => 'jwt.refresh', function() { try { $old_token ...

  10. JWT【JSON Web Token】 简述

    draft: http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html http://tools.ietf.org/html/ ...

随机推荐

  1. Note -「广义二项级数」浅赏

      上回 说到拉反和扩展拉反,那么这里先给几个小小变形或推广.   基础 ver: \[\begin{align} [x^n]G(x) &= \frac{1}{n}[x^{n-1}](F(x) ...

  2. 特斯拉CEO埃隆马.斯克的五步工作法,怎么提高工程效率加速产品开发?

    简介 在<埃隆·马斯克传>这本书中,有两个章节写到了特斯拉 CEO 埃隆马斯克为了在一段时间内,提升特斯拉汽车 model 3 的产能到每个月 5000 辆这个数量级,在书中叫 " ...

  3. 学Shiro完结版-4

    第十四章 SSL--<跟我学Shiro> 对于SSL的支持,Shiro只是判断当前url是否需要SSL登录,如果需要自动重定向到https进行访问. 首先生成数字证书,生成证书到D:\lo ...

  4. 网络通信协议:TCP(三次握手四次挥手)和UDP

    通信要素2:网络协议  网络通信协议计算机网络中实现通信必须有一些约定,即通信协议,对速率.传输代码.代码结构.传输控制步骤.出错控制等制定标准. 问题:网络协议太复杂计算机网络通信涉及内容很多, ...

  5. 1.某道翻译js逆向sign值

    首先找到这个请求接口 这个接口就是我们请求翻译的接口 发现有个sign值,这就是我们需要逆向的值 再看看这个接口的响应 可以发现这个响应是被加密的,我们还需要去逆向解密这个被加密的响应,这篇就单纯讲一 ...

  6. flutter3-dymall仿抖音直播商城|Flutter3.27短视频+直播+聊天App实例

    自研flutter3.27+dart3.6+getx实战抖音短视频+聊天+直播电商带货app商城应用. flutter_dymall一款基于最新版Flutter3.27+Dart3.x+Getx+me ...

  7. HT-014 Div3 扫雷 题解 [ 绿 ] [ 二维差分 ]

    分析 观察到是曼哈顿距离 \(\le r\) 的范围可以扫到,联想到如下图形: 左边是 \(r=1\) 可以扫到的范围,右边是 \(r=2\) 可以扫到的范围. 于是,我们只要对这样的图形在 \(10 ...

  8. CommonLang3-使用介绍

    学习要带着目的,参照现实问题 本次目标: 了解 CommonsLang3 API 文档,找对路后以后开发直接查询 API 文档,摈弃盲目的百度 掌握基础的字符串.日期.数值等工具方法,初步替代手搓的工 ...

  9. C++ 创建进程的方法

    1. C++中创建进程的代码示例: // ProcessDemo.cpp : 此文件包含 "main" 函数.程序执行将在此处开始并结束. // #include<windo ...

  10. 牛客题解 | 单组_spj判断YES与NO

    题目 题目链接 解题思路 后台有spj代码,能对同学们的输出数据进行校验,符合条件即可通过. 附赠 spj 代码 #include <iostream> #include <fstr ...