部分內容轉載自:https://www.cnblogs.com/chenwolong/p/Token.html
首先引入JWT.dll(之前的博主沒有說要下載哪個版本的,我自己親測了一下,應該是2.3.2版本的JWT包)
-------------------------------------------------------
WebApi正式開始
1、我們自定義一個繼承自System.Web.Http 命名空間下的AuthorizeAttribute 屬性來解析並驗證TOKEN

using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Text; using System.Web; using System.Web.Http; using System.Web.Http.Controllers; using TestForToken.CommonCS; namespace TestForToken.Auth2._0 { public class ApiActionAuth : AuthorizeAttribute { public override void OnAuthorization(HttpActionContext context) { var authHeader = context.Request.Headers.FirstOrDefault(a => a.Key == "ApiAuthorization");//獲取接收的Token if (context.Request.Headers == null || !context.Request.Headers.Any() || authHeader.Key == null || string.IsNullOrEmpty(authHeader.Value.FirstOrDefault())) { Throw401Exception(context, "NoToken"); return; } var sendToken = authHeader.Value.FirstOrDefault(); //url獲取token var now = Math.Round((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds + 5);//當前的時間戳 var dictPayload = DecodeToken(sendToken); if (dictPayload == null) { Throw401Exception(context, "InvalidToken"); } double iat = dictPayload["iat"]; double exp = dictPayload["exp"]; //檢查令牌的有效期 if (!(iat < now && now < exp))//如果當前時間戳不再Token聲明周期范圍內,則返回Token過期 { Throw401Exception(context, "TokenTimeout"); } //獲取Token的自定義鍵值對 int UserId = dictPayload["UserId"]; string UserName = dictPayload["UserName"]; string UserPwd = dictPayload["UserPwd"]; string UserRole = dictPayload["UserRole"]; //把toke用戶數據放到 HttpContext.Current.User 里 ClientUserData clientUserData = new ClientUserData() { UserId = UserId, UserName = UserName, UserPwd = UserPwd, UserRole = UserRole }; if (HttpContext.Current != null) { HttpContext.Current.User = new UserPrincipal(clientUserData); } } private static IDictionary<string, dynamic> DecodeToken(string token) { try { var dictPayload = JWT.JsonWebToken.DecodeToObject(token, CommonToken.SecretKey) as IDictionary<string, dynamic>; return dictPayload; } catch (Exception ex) { return null; } } private static void Throw401Exception(HttpActionContext actionContext, string exceptionString) { var response = HttpContext.Current.Response; throw new HttpResponseException( actionContext.Request.CreateErrorResponse(System.Net.HttpStatusCode.Unauthorized, exceptionString ?? "Unauthorized")); } private static string RequestToString(HttpRequestMessage request) { var message = new StringBuilder(); if (request.Method != null) message.Append(request.Method); if (request.RequestUri != null) message.Append(" ").Append(request.RequestUri); return message.ToString(); } } }
2、新增一個存儲解析Token結果的類,命名為SysHelper.cs,代碼如下:

using System; using System.Collections.Generic; using System.Linq; using System.Security.Principal; using System.Web; namespace TestForToken.Auth2._0 { public class SysHelper { public static UserPrincipal CurrentPrincipal { get { return HttpContext.Current.User as UserPrincipal; } } } public class UserPrincipal : ClientUserData, IPrincipal { public IIdentity Identity { get; private set; } public string[] Roles { get; set; } public UserPrincipal(ClientUserData clientUserData) { this.Identity = new GenericIdentity(string.Format("{0}", clientUserData.UserId)); this.UserId = clientUserData.UserId; this.UserName = clientUserData.UserName; this.UserPwd = clientUserData.UserPwd; this.UserRole = clientUserData.UserRole; } public bool IsInRole(string role) { if (Roles.Any(r => r == role)) { return true; } else { return false; } } } public class ClientUserData { public int UserId { get; set; } public string UserName { get; set; } public string UserPwd { get; set; } public string UserRole { get; set; } } }
3、公共Token生成方法修改如下:

using System; using System.Collections.Generic; using System.Linq; using System.Web; /*---------------------------------------------------------------- Copyright (C) 2017 陳卧龍 文件名:TestForToken.CommonCS 文件功能描述:Token相關操作 ----------------------------------------------------------------*/ namespace TestForToken.CommonCS { public class CommonToken { public static string SecretKey = "This is a private key for Server";//這個服務端加密秘鑰 屬於私鑰 public static string GetToken(TokenInfo M) { var jwtcreated = Math.Round((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds + 5); var jwtcreatedOver = Math.Round((DateTime.UtcNow.AddHours(2) - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds + 5);//TOKEN聲明周期二小時 var payload = new Dictionary<string, dynamic> { {"iss", M.iss},//非必須。issuer 請求實體,可以是發起請求的用戶的信息,也可是jwt的簽發者。 {"iat", jwtcreated},//非必須。issued at。 token創建時間,unix時間戳格式 {"exp", jwtcreatedOver},//非必須。expire 指定token的生命周期。unix時間戳格式 {"aud", M.aud},//非必須。接收該JWT的一方。 {"sub", M.sub},//非必須。該JWT所面向的用戶 {"jti", M.jti},//非必須。JWT ID。針對當前token的唯一標識 {"UserId", M.UserId},//自定義字段 用於存放當前登錄人賬戶信息 {"UserName", M.UserName},//自定義字段 用於存放當前登錄人賬戶信息 {"UserPwd", M.UserPwd},//自定義字段 用於存放當前登錄人登錄密碼信息 {"UserRole", M.UserRole},//自定義字段 用於存放當前登錄人登錄權限信息 }; return JWT.JsonWebToken.Encode(payload, SecretKey, JWT.JwtHashAlgorithm.HS256); } } public class TokenInfo { public TokenInfo() { iss = "簽發者信息"; aud = "http://example.com"; sub = "HomeCare.VIP"; jti = DateTime.Now.ToString("yyyyMMddhhmmss"); UserId = 1; UserName = "jack.chen"; UserPwd = "jack123456"; UserRole = "HomeCare.Administrator"; } // public string iss { get; set; } public string aud { get; set; } public string sub { get; set; } public string jti { get; set; } public int UserId { get; set; } public string UserName { get; set; } public string UserPwd { get; set; } public string UserRole { get; set; } } }