ASP.NET WebApi 如何使用 OAuth2.0 认证

image

前言

OAuth 2.0 是一种开放标准的授权框架,用于授权第三方应用程序访问受保护资源的流程。

OAuth 2.0 认证是指在这个框架下进行的身份验证和授权过程。

在 OAuth 2.0 认证中,涉及以下主要参与方:

  1. 资源所有者(Resource Owner): 拥有受保护资源的用户。
  2. 客户端(Client): 第三方应用程序,希望访问资源所有者的受保护资源。
  3. 授权服务器(Authorization Server): 负责验证资源所有者的身份并颁发访问令牌。
  4. 资源服务器(Resource Server): 存储受保护资源的服务器,用于接收和响应客户端请求。

OAuth 2.0 认证的流程通常包括以下步骤:

  1. 客户端注册: 客户端向授权服务器注册,并获得客户端标识和客户端密钥。
  2. 请求授权: 客户端向资源所有者请求授权,以获取访问受保护资源的权限。
  3. 授权许可: 资源所有者同意授权,授权服务器颁发授权码给客户端。
  4. 获取访问令牌: 客户端使用授权码向授权服务器请求访问令牌。
  5. 访问受保护资源: 客户端使用访问令牌向资源服务器请求访问受保护资源。

OAuth 2.0 认证的优势在于可以实现用户授权而无需透露密码,同时提供了更安全和灵活的授权机制,更好地保护用户数据和系统安全。

以下是一个 ASP.NET WebApi 简单使用 OAuth2.0 认证的 Step By Step 例子。

Step By Step 步骤

  1. 新建一个空 ASP.NET WebApi 项目,比如 TokenExample

  2. 在 Models 目录下新建一个 Product 实体类:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;namespace TokenExample.Models
    {public class Product{public int Id { get; set; }public string Name { get; set; }public string Category { get; set; }public decimal Price { get; set; }}
    }
    
  3. 在 Controllers 目录下新建一个 ProductsController 控制器

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Http;
    using System.Web.Http;
    using TokenExample.Models;namespace TokenExample.Controllers
    {public class ProductsController : ApiController{// 初始化数据Product[] products = new Product[]{new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 },new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M },new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M }};// 查找所有的产品public IEnumerable<Product> GetAllProducts(){return products;}// 根据 id 查找产品public Product GetProductById(int id){var product = products.FirstOrDefault((p) => p.Id == id);if (product == null){throw new HttpResponseException(HttpStatusCode.NotFound);}return product;}// 根据 类别 查找产品public IEnumerable<Product> GetProductsByCategory(string category){return products.Where(p => string.Equals(p.Category, category, StringComparison.OrdinalIgnoreCase));}}
    }
    
  4. 将网站部署到 IIS, 端口为 8080,使用 Postman 工具测试以下 api:

    GET http://localhost:8080/api/Products
    GET http://localhost:8080/api/Products/1
    GET http://localhost:8080/api/Products?category=Groceries
    

    可以看到这些 API 都是可以公开访问的,没有任何验证

  5. 在 WebApi 项目右键,选择 “管理 Nuget 程序包”,打开 Nuget 包管理器 GUI, 安装以下包:

    Microsoft.AspNet.WebApi.Owin
    Microsoft.Owin.Host.SystemWeb
    Microsoft.AspNet.Identity.Owin
    Microsoft.Owin.Cors
    EntityFramework

  6. 在项目根目录下添加 “Startup” 类, 这是 Owin 的启动类(注意是项目根目录,即跟 Global.asax 同一位置)

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Http;
    using Owin;
    using Microsoft.Owin;
    using Microsoft.Owin.Security.OAuth;[assembly: OwinStartup(typeof(TokenExample.Startup))]
    namespace TokenExample
    {public class Startup{public void Configuration(IAppBuilder app){HttpConfiguration config = new HttpConfiguration();ConfigureOAuth(app);WebApiConfig.Register(config);app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);app.UseWebApi(config);}public void ConfigureOAuth(IAppBuilder app){OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions(){AllowInsecureHttp = true,// 这里设置获取 token 有 url pathTokenEndpointPath = new PathString("/token"),AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),Provider = new SimpleAuthorizationServerProvider()};app.UseOAuthAuthorizationServer(OAuthServerOptions);app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());}}
    }
    
  7. 删除 Global.asax

    • NOTE: 设置了 Startup 类, 就不需要 Global.asax 了,可以删除,也可以留着
  8. 在项目根目录下添加验证类 SimpleAuthorizationServerProvider

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;using System.Threading;
    using System.Threading.Tasks;
    using Microsoft.Owin;
    using Microsoft.Owin.Security.OAuth;
    using System.Security.Claims;namespace TokenExample
    {public class SimpleAuthorizationServerProvider: OAuthAuthorizationServerProvider{public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context){context.Validated();}public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context){// 设置允许跨域context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });/** 对用户名、密码进行数据校验,这里我们省略using (AuthRepository _repo = new AuthRepository()){IdentityUser user = await _repo.FindUser(context.UserName, context.Password);if (user == null){context.SetError("invalid_grant", "The user name or password is incorrect.");return;}}*/var identity = new ClaimsIdentity(context.Options.AuthenticationType);identity.AddClaim(new Claim("sub", context.UserName));identity.AddClaim(new Claim("role", "user"));context.Validated(identity);}}
    }
    
  9. 修改 ProductsController 类,在 Action 上增加 [Authorize] 特性,代码如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Http;
    using System.Web.Http;
    using TokenExample.Models;namespace TokenExample.Controllers
    {public class ProductsController : ApiController{Product[] products = new Product[]{new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 },new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M },new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M }};// [Authorize] 特性是启用 OAuth 的 Access Token 验证,让 CORS 起作用[Authorize]public IEnumerable<Product> GetAllProducts(){return products;}[Authorize]public Product GetProductById(int id){var product = products.FirstOrDefault((p) => p.Id == id);if (product == null){throw new HttpResponseException(HttpStatusCode.NotFound);}return product;}// [AllowAnonymous] 特性是允许匿名访问,即无需 Access Token 验证[AllowAnonymous]public IEnumerable<Product> GetProductsByCategory(string category){return products.Where(p => string.Equals(p.Category, category, StringComparison.OrdinalIgnoreCase));}}
    }
    

测试

  1. 重新在 Postman 运行以下命令:

    GET http://localhost:8080/api/Products
    返回:
    {"Message": "已拒绝为此请求授权。"
    }
    这是预期的
    
  2. 在 Postman 运行以下命令:

    POST/GET http://localhost:23477/token
    参数 BODY x-www-form-urlencoded 格式:
    grant_type=password
    username=admin 
    password=123456返回:
    {"access_token": "ESWxgOCWDDPBRg37cX2RIAb8h--AYgz55rheYumSEU9YVjikYowyih1EdkVUg5vEeuLEeuhZPFJFGe33N3yvieYCzVQ2r0FKYBj0vydKnHAZ7CpLry4DaOhZ8JKIxa159QiBZubA_YgtFliUggSefiosrXW-FaUUO-m5th4YwInw2_5aGPL73uB5FYE0LcLN51U8ZlqoeLDChO3MdTigTc90rVUNiiZ3UBHn-HWvSnI","token_type": "bearer","expires_in": 86399
    }
    
  3. 在以下 api 的 Headers 加上:

    GET http://localhost:8080/api/Products
    Headers
    Key: Authorization
    Value: bearer ESWxgOCWDDPBRg37cX2RIAb8h--AYgz55rheYumSEU9YVjikYowyih1EdkVUg5vEeuLEeuhZPFJFGe33N3yvieYCzVQ2r0FKYBj0vydKnHAZ7CpLry4DaOhZ8JKIxa159QiBZubA_YgtFliUggSefiosrXW-FaUUO-m5th4YwInw2_5aGPL73uB5FYE0LcLN51U8ZlqoeLDChO3MdTigTc90rVUNiiZ3UBHn-HWvSnI
    
  4. 重新运行,即可正常访问,至此就完成了简单的 ASP.NET WebApi 使用 OAuth2.0 认证

总结

  1. OAuth2.0 有 Client 和 Scope 的概念,JWT 没有,如果只是拿来用于颁布 Token 的话,二者没区别,如本例
  2. OAuth2.0 和 JWT 在使用 Token 进行身份验证时有相似之处,但实际上它们是完全不同的两种东西,OAuth2.0 是授权认证的框架,JWT 则是认证验证的方式方法(轻量级概念)
  3. OAuth2.0 更多用在使用第三方账号登录的情况(比如使用 weibo,qq,github 等登录某个 app)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/324903.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springboot 引入第三方bean

如何进行第三方bean的定义 参数进行自动装配

PCB检查

文章目录 1、打开DRC2、database check3、检查DRC4、检查多余的线5、其他需要注意的点a.检查差分线、等长线是否已调好b.注意检查晶振、电感等元件上/下方是否其他线经过&#xff08;一般不允许线经过&#xff09;c.打开place_bound_top/bottom 检查元件是否超过这个允许范围d.…

【高校科研前沿】北师大陈晋教授团队在遥感顶刊发表最新成果:ClearSCD模型:在高空间分辨率遥感影像中综合利用语义和变化关系进行语义变化检测

01文章简介 论文名称&#xff1a;The ClearSCD model: Comprehensively leveraging semantics and change relationships for semantic change detection in high spatial resolution remote sensing imagery&#xff08;ClearSCD模型&#xff1a;在高空间分辨率遥感影像中综合…

【GESP】2023年12月图形化二级 -- 小杨报数

小杨报数 【题目描述】 小杨需要从 1 1 1到 N N N报数。在报数过程中&#xff0c;小杨希望跳过 M M M的倍数。例如&#xff0c;如果 N 5 N5 N5&#xff0c; M 2 M2 M2&#xff0c;那么小杨就需要依次报出 1 1 1&#xff0c; 3 3 3&#xff0c; 5 5 5。 默认小猫角色和白色背…

桥接模式类图与代码

欲开发一个绘图软件&#xff0c;要求使用不同的绘图程序绘制不同的图形。以绘制直线和圆形为例&#xff0c;对应的绘图程序如表 7.7 所示。 根据绘图软件的扩展性要求&#xff0c;该绘图软件将不断扩充新的图形和新的绘图程序。为了避免出现类爆炸的情况&#xff0c;现采用桥接…

车辆运动模型中LQR代码实现

一、前言 最近看到关于架构和算法两者关系的一个描述&#xff0c;我觉得非常认同&#xff0c;分享给大家。 1、好架构起到两个作用&#xff1a;合理的分解功能、合理的适配算法&#xff1b; 2、好的架构是好的功能的必要条件&#xff0c;不是充分条件&#xff0c;一味追求架构…

Scala编程入门:从零开始的完整教程

目录 引言环境准备创建第一个Scala项目基本语法高阶概念进阶资源结语 引言 Scala是一种强大的、静态类型的、多范式编程语言&#xff0c;它结合了面向对象和函数式编程的特点。本教程将指导您如何从零开始学习Scala&#xff0c;并搭建一个简单的开发环境。让我们开始探索Scala…

webassembly入门详解(C++)

一、环境配置 环境说明,操作系统为window操作系统。 1.1 下载和安装python 下载 需要python版本至少3.6版本 python下载地址:https://www.python.org/getit/ 安装 检测安装结果 win+R组合键->cmd->输入python->回车 1.2 下载和安装emsdk 下载 下载地址:https://gi…

春秋云镜 CVE-2022-4230

靶标介绍&#xff1a; WP Statistics WordPress 插件13.2.9之前的版本不会转义参数&#xff0c;这可能允许经过身份验证的用户执行 SQL 注入攻击。默认情况下&#xff0c;具有管理选项功能 (admin) 的用户可以使用受影响的功能&#xff0c;但是该插件有一个设置允许低权限用户…

Spring Security基础教程:从入门到实战

作者介绍&#xff1a;✌️大厂全栈码农|毕设实战开发&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。 推荐订阅精彩专栏 &#x1f447;&#x1f3fb; 避免错过下次更新 Springboot项目精选实战案例 更多项目&#xff1a;CSDN主页YAML墨韵 学如逆水行舟&#xff0c…

LOTO示波器动作编程功能(命令批处理)

动作编程功能是为了方便客户根据自己的应用场景&#xff0c;做到一个按键就连续做多个示波器操作&#xff0c;从而降低了对操作人员的技术要求&#xff0c;做到傻瓜式操作。之前LOTO有个类似的功能&#xff0c;是把示波器的基础设置根据不同的测试场景存成不同的设置文件&#…

新建的springBoot WEB项目无法自动返回html模版(gradle+kotlin版本)

最近研究了springBoot创建web项目&#xff0c; 第一步服务端返回字符串没有问题&#xff0c;第二步返回html时&#xff0c;还是返回的字符串。 文章目录 一、参考方案二、新建springBoot web项目三、启动项目的三种方式 一、参考方案 将控制器类的 RestController 改为 Contro…

基于CCS5.5的双音多频(DTMF)信号检测仿真实验(①检测型音频文件②输入生成音频并检测)

DTMF的优点 我们知道,DTMF根本上仍然是频谱分析,基础还是DFT,但DFT通常需要对一整段数据做变换,而DTMF不同,每输入一个采样点就计算一次,更有利于硬件实现。 基于CCS的双音多频(DTMF)信号检测原理 公式详细推导 详细的公式推导在下面这篇博客中已经进行了详细的描述,…

AI图书推荐:给自媒体创作者的ChatGPT使用指南

你是否厌倦了花费数小时盯着空白屏幕&#xff0c;努力为你的内容想出新鲜点子&#xff1f;想要将你的写作提升到下一个水平&#xff1f;有了ChatGPT&#xff0c;你可以告别写作障碍、无休止的修订和浪费的时间。 在这本全面的指南中&#xff0c;你将学到关于ChatGPT你需要知道…

vue3使用el-autocomplete请求远程数据

服务器端 RestController RequestMapping("/teacher") public class TeacherController {Resourceprivate TeacherService teacherService;GetMapping({"/v1/getTop10TeacherByName/","/v1/getTop10TeacherByName/{name}"})public ResultBean&l…

工业机器人应用实践之玻璃涂胶(篇二)

工业机器人 接上篇文章&#xff0c;浅谈一下实践应用&#xff0c;具体以玻璃涂胶为例&#xff1a; 了解工业机器人在玻璃涂胶领域的应用认识工具坐标系的标定方法掌握计时指令的应用掌握人机交互指令的应用掌握等待类指令用法&#xff08;WaitDI、WaitUnitl 等&#xff09;认…

【gpedit.msc】组策略编辑器的安装,针对windows家庭版,没有此功能

创建一个记事本文件然后放入以下内容 echo offpushd "%~dp0"dir /b %systemroot%\Windows\servicing\Packages\Microsoft-Windows-GroupPolicy-ClientExtensions-Package~3*.mum >gp.txtdir /b %systemroot%\servicing\Packages\Microsoft-Windows-GroupPolicy-…

进程间通信

文章目录 1.进程间通信2.进程间通信方式2.1 管道---匿名管道2.2 使用管道---管道测试接口(代码实现) 3.进程池3.1 进程池的原理图3.2 进程池的代码实现 4.命名管道4.1 有名管道通信4.2 有名管道通信的代码实现 5.共享内存5.1 共享内存原理5.2 共享内存的代码实现 6.共享内存7.代…

Ubuntu24.04安装中文输入法

Ubuntu24.04安装中文输入法 为了更好的体验&#xff0c;请访问个人博客 www.huerpu.cc:7000 一、添加中文语言支持 在安装中文输入法之前&#xff0c;首选要添加中文语言支持。选择System&#xff0c;点击Region & Language。 点击Manage Install Languages。 点击Insta…

MongoDB安装及接入springboot

环境&#xff1a;windows、jdk8、springboot2 1.MongoDB概述 MongoDB是一个开源、高性能、无模式&#xff08;模式自由&#xff09;的文档&#xff08;Bson&#xff09;型数据库&#xff1b;其特点如下&#xff1a; 模式自由 ---- 不需要提前创建表 直接放数据就可以 支持高并…