.Net WebAPI JWT身份验证

2023-11-11

一、开发环境

VS2017  enterprise

win10 Pro 64

.net 4.6.2

二、开发过程

1、使用VS2017 创建.netframework项目,选择WebApi

2、从Nuget包中搜索并安装JWT

3、在Models中创建AuthInfo.cs、LoginRequest.cs、TokenInfo.cs三个类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace apiToken.Models
{
    /// <summary>
    /// 身份验证信息 模拟JWT的payload
    /// </summary>
    public class AuthInfo
    {
        /// <summary>
        /// 用户名
        /// </summary>
        public string UserName { get; set; }

        /// <summary>
        /// 角色
        /// </summary>
        public List<string> Roles { get; set; }

        /// <summary>
        /// 是否管理员
        /// </summary>
        public bool IsAdmin { get; set; }

        /// <summary>
        /// 口令过期时间
        /// </summary>
        public DateTime? ExpiryDateTime { get; set; }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace apiToken.Models
{
    /// <summary>
    /// 登录用户信息
    /// </summary>
    public class LoginRequest
    {
        /// <summary>
        /// 用户名
        /// </summary>
        public string UserName { get; set; }

        /// <summary>
        /// 密码
        /// </summary>
        public string Password { get; set; }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace apiToken.Models
{
    /// <summary>
    /// 生成的口令信息
    /// </summary>
    public class TokenInfo
    {
        /// <summary>
        /// 是否成功
        /// </summary>
        public bool Success { get; set; }
        /// <summary>
        /// 令牌
        /// </summary>
        public string Token { get; set; }
        /// <summary>
        /// 错误信息
        /// </summary>
        public string Message { get; set; }
    }
}

4、在Controllers文件夹下创建TokenController.cs文件,生成口令

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using JWT;
using JWT.Algorithms;
using JWT.Serializers;
using apiToken.Models;
using System.Text;

namespace apiToken.Controllers
{
    [RoutePrefix("api/Token")]
    public class TokenController : ApiController
    {
        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="loginRequest"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("Login")]
        public TokenInfo Login([FromBody] LoginRequest loginRequest)
        {
            TokenInfo tokenInfo = new TokenInfo();//需要返回的口令信息
            if (loginRequest != null)
            {
                string userName = loginRequest.UserName;
                string passWord = loginRequest.Password;
                bool isAdmin = (userName == "admin")?true:false;
                //模拟数据库数据,真正的数据应该从数据库读取
                //身份验证信息
                AuthInfo authInfo = new AuthInfo { UserName=userName,Roles=new List<string> {"admin","commonrole"}, IsAdmin= isAdmin, ExpiryDateTime=DateTime.Now.AddHours(2)};
                const string secretKey = "Hello World";//口令加密秘钥
                try
                {
                    byte[] key = Encoding.UTF8.GetBytes(secretKey);
                    IJwtAlgorithm algorithm = new HMACSHA256Algorithm();//加密方式
                    IJsonSerializer serializer = new JsonNetSerializer();//序列化Json
                    IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();//base64加解密
                    IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);//JWT编码
                    var token = encoder.Encode(authInfo, key);//生成令牌
                    //口令信息
                    tokenInfo.Success = true;
                    tokenInfo.Token = token;
                    tokenInfo.Message = "OK";
                }
                catch(Exception ex)
                {
                    tokenInfo.Success = false;
                    tokenInfo.Message = ex.Message.ToString();
                }
            }
            else
            {
                tokenInfo.Success = false;
                tokenInfo.Message = "用户信息为空";
            }
            return tokenInfo;
        }

        
    }
}

5、在项目中添加AuthAttributes文件夹,并且在文件夹在创建ApiAuthorizeAttribute.cs文件,用于创建身份拦截器

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Http.Controllers;
using JWT;
using JWT.Serializers;
using apiToken.Models;
using System.Text;
using System.Net;
using System.Net.Http;

namespace apiToken.AuthAttributes
{
    /// <summary>
    /// 身份认证拦截器
    /// </summary>
    public class ApiAuthorizeAttribute: AuthorizeAttribute
    {
        /// <summary>
        /// 指示指定的控件是否已获得授权
        /// </summary>
        /// <param name="actionContext"></param>
        /// <returns></returns>
        protected override bool IsAuthorized(HttpActionContext actionContext)
        {
            //前端请求api时会将token存放在名为"auth"的请求头中
            var authHeader = from t in actionContext.Request.Headers where t.Key == "auth" select t.Value.FirstOrDefault();
            if (authHeader != null)
            {
                const string secretKey = "Hello World";//加密秘钥
                string token = authHeader.FirstOrDefault();//获取token
                if (!string.IsNullOrEmpty(token))
                {
                    try
                    {
                        byte[] key = Encoding.UTF8.GetBytes(secretKey);
                        IJsonSerializer serializer = new JsonNetSerializer();
                        IDateTimeProvider provider = new UtcDateTimeProvider();
                        IJwtValidator validator = new JwtValidator(serializer, provider);
                        IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
                        IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder);
                        //解密
                        var json = decoder.DecodeToObject<AuthInfo>(token, key, verify: true);
                        if (json != null)
                        {
                            //判断口令过期时间
                            if (json.ExpiryDateTime < DateTime.Now)
                            {
                                return false;
                            }
                            actionContext.RequestContext.RouteData.Values.Add("auth", json);
                            return true;
                        }
                        return false;
                    }
                    catch (Exception ex)
                    {
                        return false;
                    }
                }
            }
            return false;
        }

        /// <summary>
        /// 处理授权失败的请求
        /// </summary>
        /// <param name="actionContext"></param>
        protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
        {
            var erModel = new
            {
                Success="false",
                ErrorCode="401"
            };
            actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.OK, erModel, "application/json");
        }

        /// <summary>
        ///  为操作授权时调用
        /// </summary>
        /// <param name="actionContext"></param>
        //public override void OnAuthorization(HttpActionContext actionContext)
        //{
          
        //}
    }
}

6、创建UserInfoController.cs 用于测试身份验证

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using apiToken.AuthAttributes;
using Newtonsoft.Json;

namespace apiToken.Controllers
{
    [RoutePrefix("api/UserInfo")]
    [ApiAuthorize]
    public class UserInfoController : ApiController
    {
        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Route("GetUserInfo")]
        public string GetUserInfo()
        {
            var userInfo = new
            {
                UserName="test",
                Tel="123456789",
                Address="testddd"
            };
            return JsonConvert.SerializeObject(userInfo);
        }       
    }
}

最后将webapi接口在IIS中发布,通过PostMan进行测试

如果Token不正确或者Token失效则不会进入请求

注:如果遇到跨域的问题,可以下webconfig中做如下配置

想要更详细的了解Nuget中的JWT的使用,可通过此链接学习https://github.com/jwt-dotnet/jwt

需要源码程序可同学可通过此链接下载 https://download.csdn.net/download/liwan09/10769921

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

.Net WebAPI JWT身份验证 的相关文章

  • C#动态支持吗?

    看完之后这个帖子 https stackoverflow com questions 2674906 when should one use dynamic keyword in c sharp 4 0k和链接 我还有 2 个问题 问题 1
  • 为什么要序列化对象需要 Serialized 属性

    根据我的理解 SerializedAttribute 不提供编译时检查 因为它都是在运行时完成的 如果是这样 那么为什么需要将类标记为可序列化呢 难道序列化器不能尝试序列化一个对象然后失败吗 这不就是它现在所做的吗 当某些东西被标记时 它会
  • 是否可以有一个 out ParameterExpression?

    我想定义一个 Lambda 表达式out范围 有可能做到吗 下面是我尝试过的 C Net 4 0 控制台应用程序的代码片段 正如您在 procedure25 中看到的 我可以使用 lambda 表达式来定义具有输出参数的委托 但是 当我想使
  • 如何从进程开始捕获所有应用程序/窗口消息? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我试图弄清楚如何捕获进程 窗口的所有窗口消息 从它在 c 中启动时开始 该过程不是我自己的 所以我需要使用某种钩子 我的目标是开始实时
  • 如何使用 Roslyn 通过扩展方法、静态类中的方法以及带有 ref/out 参数的方法来访问调用

    我正在致力于创建一个开源项目 用于创建 NET UML 序列图 该项目利用名为 js sequence diagrams 的 javascript 库 我不确定 Roslyn 是适合这项工作的工具 但我想我应该尝试一下 所以我整理了一些概念
  • C# 中的 C/C++ 代码编译器

    在 C 中 我可以使用下面的代码编译 VB 和 C 代码 但无法编译 C C 代码 有什么办法可以做到这一点吗 C 编译器 public void Compile string ToCompile string Result null st
  • 在哪里可以下载没有 Visual Studio 2010 的 C# 4.0 编译器?

    我知道 CTP VS 2010 映像 但我可以只下载 NET Framework 4 0 和 C 编译器吗 AFAIK VS 2010 CTP 仅作为 VM 映像提供 我不相信 Microsoft 发布了 VS 的安装程序 其中一个绝对不适
  • 为什么处置/关闭 WCF 客户端代理很重要

    我听说即使在以下情况下也必须处置 或关闭 WCF 客户端代理 你没有使用会话 没有需要确定性清理的非托管资源 例如打开的套接字 例如 当使用具有默认绑定配置的 BasicHttpBinding 时 即使在流行的网页中也应该没问题 对吧 va
  • 适合 .Net 开发人员的 Grails/Roo

    我目前正在学习 Grails 和 Roo 绝大多数培训材料都是针对新开发人员或现有 Java 开发人员 有谁知道使用 Net C ASP Net Asp Net MVC 翻译现有开发经验的任何指南 资源或技巧 你做过很多 ASP MVC 吗
  • 如何使用 XmlSerializer 在大文档中插入节点

    我有一个很大的 XML 文档 我想使用XmlSerializer类来插入新元素 其内容来自使用 xsd exe 生成的 NET 类实例 这是问题的后续如何使用 XmlSerializer 反序列化大型文档中的节点 https stackov
  • 文件是通过 Visual Studio 下载的,但不是通过 .exe 下载的

    当我尝试下载 a 时出现以下错误 pdf通过我的网址从文件 exe file 服务器违反了协议 部分 响应头 详细信息 CR 后必须跟 LF 但当我尝试从 Visual Studio 调试代码时 也会下载同样的内容 我完全迷失了 不知道发生
  • xmlns 元素的顺序重要吗

    我不知道如何在 google 中搜索此内容 但是 xmlns 元素的问题在 XML 文件中重要吗 我正在 ASP NET VB 中使用 XMLWriter 创建一个 XML 文件 并且尝试匹配我提供的示例
  • 使用 Rhino Mocks 存根只读属性

    我有一个带有私有集属性的类 我想用犀牛模拟来消除它 但是 当我尝试执行此操作时 它会出现编译时错误 提示我无法设置只读属性 我是使用 Rhino Mocks 的新手 所以我一定在这里遗漏了一些东西 public Interface IFoo
  • 如何在 TeamCity 的 .NET 项目中包含解决方案目录之外的依赖项

    我的解决方案目录之外有类库 因此我在 sln 文件 SomeDependency csproj 中有这样的引用 在 VS 中一切正常 但在尝试构建我的解决方案时 TeamCity 失败了 我猜它复制了所有解决方案目录 因此关系不再存在 这是
  • 如何记录所有抛出的异常?

    如何记录抛出和捕获的任何异常 就像 Visual Studio 的 IntelliTrace 所做的那样 或者有没有办法将 InteliTrace 集成到应用程序的调试版本中 然后查看其日志 Update 我会稍微澄清一下 我想要标准 tx
  • 将 MVC 操作结果发送到打印机

    我有一个带有操作的控制器 SomeController ActionToBePrinted ActionToBePrinted 返回一个 html 视图 当按下按钮时 从普通的 mvc razor 视图调用此操作 当按下按钮时 我将如何将视
  • 从网络共享运行 .NET 4.0 应用程序时出现异常

    我有一个 NET 4 0 C 控制台应用程序 该应用程序被部署到网络文件共享 我相信是 Windows 2000 Server 文件服务器 如下所示 server share Apps Beta Group JobName JobName
  • .NET 可移植类库中的 .ToShortDateString 发生了什么

    我想知道为什么没有 ToShortDateString在 NET 可移植类库中 我有 2 个项目 Silverlight 和常规 NET 类库 使用相同的代码 并且代码涉及调用 ToShortDateString on a DateTime
  • 当格式字符串包含“{”时,String.Format 异常

    我正在使用 VSTS 2008 C Net 2 0 执行以下语句时 String Format 语句抛出 FormatException 有什么想法是错误的吗 这是获取我正在使用的 template html 的位置 我想在 templat
  • 为什么我不能在扩展 List 的类中调用 OrderBy?

    我有一堂课 Deck 其中包含一个名为的方法Shuffle 我正在致力于重构Deck延长List

随机推荐

  • yum安装软件时报错libmysqlclient.so.18()(64bit)

    环境 CentOS 7 4 使用阿里yum的网络源 问题 使用yum安装软件时报错 2 postfix 2 10 1 6 el7 x86 64 has missing requires of libmysqlclient so 18 64b
  • PyQt5中为QTextEdit的某些字符单独设置大小和颜色

    QTextEdit支持富文本 因此您可以将css样式与html一起用于QTextEdit中的文本 可以使用不同的样式附加不同的富文本 为方便起见 只需创建一些格式化文本 并将相应的文本传递给python string的format方法来创建
  • [Linux安装软件详解系列]01 安装MySQL8.0

    目录 1 检查有没有安装MySQL 2 安装MySQL8 0 1 下载 rpm文件 2 上传rpm文件到服务器 3 安装rpm文件 4 查看安装好的包 5 安装MySQL 5 启动MySQL 3 本地登录 1 查看默认密码 2 本地登录My
  • 这注定是一场独一无二的旅行——周年纪念日 [form 2022 to 2023]

    啊哈 竟然已经一周年了 还记得自己写了两三篇博客以后 就停写了很久 很久 总是因为各种各样的事情拖沓 直到有一天CSDN轻轻敲醒了我沉睡的心灵 忽然意识到自己好久没写了 也让我去想自己的初衷 为何而写 Why 一直觉得内容创作是一个很酷的事
  • 华为OD机试 Python 查找人名

    描述 有一串由逗号分隔的人名 每个人名可能由一个或多个单词组成 请你设计一个方法 根据指定的前缀串 找出与前缀匹配的人名 前缀串的构造是由人名中每个单词的第一个字母组合而成 输入 一串用逗号分隔的人名 一个前缀串 输出 匹配前缀串的所有人名
  • 吴恩达机器学习之路---logistic regression

    logistic regression 一 Logistic 回归 利用matlib实现 基础版 1 logistic regression数学基础 1 1 此示例为二元分类 二元分类的最终预测结果h为 0 1 为获得此效果 使用sigmo
  • 02-----带宽分析-----码流、分辨率、帧率的概念及如何计算视频带宽

    相关文章 01 带宽分析 下载nmon分析软件 一 码流 分辨率 帧率的概念 1 码流 码流 Data Rate 是指视频文件在单位时间内使用的数据流量 也叫码率或码流率 是视频编码中画面质量控制中最重要的部分 一般我们用的单位是Kb s或
  • Java线程学习实例——采用同步锁,互斥锁与同步锁的区别,synchronized的使用方法

    栗子来源 https blog csdn net wenzhi20102321 article details 52524545 首先对java中同步锁与互斥锁进行区分 主要来源于知乎中的大佬总结如下 1 锁的概念 锁的目的就是避免多个线程
  • FTP服务器的文件模式属于,FTP服务器的文件模式属于

    FTP服务器的文件模式属于 内容精选 换一换 在SAP HANA系统中 Shared卷和Backup卷由SFS Turbo提供时 需要创建一个SFS Turbo 提供共享路径给SAP HANA节点 表1列出了弹性文件服务的常用功能 在使用弹
  • uc浏览器解析视频源码,不废话,直接源码

    package cn rs blog service jiexi import com jfinal kit HttpKit import org apache http client CookieStore import org apac
  • 计算时间复杂度--(简单版)

    步骤 1 找到执行次数最多的语句 2 语句执行语句的数量级 3 用O表示结果 计算时间复杂度的3个出发点 掌握这三个出发点 那么一向搞不懂的时间复杂度就可以迎刃而解啦 然后 1 用常数1取代运行时间中的所有加法常数 2 在修改后的运行次数函
  • Spark(火花)快速、通用的大数据处理引擎框架

    一 什么是Spark 火花 是一种快速 通用处理大数据分析的框架引擎 二 Spark的四大特性 1 快速 Spark内存上采用DAG 有向无环图 执行引擎非循环数据流和内存计算支持 内存上比MapReduce快速100倍 磁盘上快10倍左右
  • android surfaceflinger 老罗,「Android」SurfaceFlinger分析

    本篇针对surfaceFlinger模块进行分析 目录如下 1 SurfaceFlinger功能 1 1 BufferQueue原理 native libs gui模块 1 2 layer显示内存分配 native libs ui模块 1
  • 使用org.apache.tools.zip包操作文件

    import java io import org apache tools zip import java util Enumeration 功能 zip压缩 解压 支持中文文件名 说明 本程序通过使用Apache Ant里提供的zip工
  • pytorch中的torchvision.transforms模块详解

    torchvision transforms torchvision transforms是pytorch中的图像预处理包 包含了很多种对图像数据进行变换的函数 这些都是在我们进行图像数据读入步骤中必不可少的 data transforms
  • 最大最小爬山算法的一些总结

    据说MMHC是现行的比较成功的一种混合贝叶斯结构学习算法 其主要思想是 先建立一个贝叶斯网络的骨架 再通过贪心算法确定最终结构 那么要搞懂的是以下 1 框架是如何建立的 2 贪心算法是怎么运行的 3 最大最小体现在哪里 4 为什么会优于一般
  • Linux 关闭无用端口

    Linux 关闭无用端口 关闭系统不必要的端口 增强系统安全 此处以关闭111端口为例进行说明 查看本机正在监听的端口 netstat tlnup 查看正在监听的111端口 由哪个服务使用 cat etc services grep w 1
  • Adobe XD for Mac v35.2.12 界面设计和原型交互工具

    Adobe XD for Mac 是一款优秀的界面设计和原型交互工具 用户可以进行移动应用和网页设计与原型制作 同时它也是唯一一款结合设计与建立原型功能 并同时提供工业级性能的跨平台设计产品 设计师使用Adobe XD可以更高效准确的完成静
  • 继承中析构和构造的调用原则

    继承与组合混搭情况下 构造和析构调用原则 先说结论 原则 先构造父类 再构造成员变量 最后构造自己 先析构自己 在析构成员变量 最后析构父类 注 先构造的对象 后释放 class my 创建一个成员类 public int a my int
  • .Net WebAPI JWT身份验证

    一 开发环境 VS2017 enterprise win10 Pro 64 net 4 6 2 二 开发过程 1 使用VS2017 创建 netframework项目 选择WebApi 2 从Nuget包中搜索并安装JWT 3 在Model