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.pswp.cn/web/10356.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/10356.shtml
英文地址,請注明出處:http://en.pswp.cn/web/10356.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【.NET Cote】你真的了解HttpRuntime類嗎

【.NET Cote】你真的了解HttpRuntime類嗎 文章目錄 【.NET Cote】你真的了解HttpRuntime類嗎一、HttpRuntime概述二、HttpRuntime是什么包三、HttpRuntime屬性四、HttpRuntime方法五、HttpRuntime.Cache方法六、HttpRuntime.Cache應用 一、HttpRuntime概述 C# HttpRuntime是一…

JAVA基礎之下載,socket實現網絡聊天

目錄 一、如何利用正則表達式找到img標簽 compile編譯編制 二、下載圖片的方法 三、socket實現網絡聊天 1.inputStreamReader 字節的讀取流--->字符的讀取流 2.outputStreamWriter 字節的寫入流--->字符的寫入流 一、如何利用正則表達式找到img標簽 compile編譯編制…

antd組件狀態變換為啥要使用剪頭函數

先看下代碼 import React, {useState} from react; import {Switch, Typography} from antd;const {Paragraph, Text} Typography;const App: React.FC () > { const [ellipsis, setEllipsis] useState(true);return (<>//正確的<Switch checked{ellipsis}onCh…

掌握SQL的時間序列分析利器:LEAD與LAG函數詳解

在SQL中&#xff0c;處理時間序列數據時&#xff0c;經常需要查看當前行與相鄰行之間的關系。這時&#xff0c;LEAD和LAG兩個窗口函數就顯得尤為重要。它們允許我們訪問結果集中的前一行或后一行的數據&#xff0c;為數據分析和處理提供了極大的便利。本文將詳細介紹LEAD和LAG函…

steam_api64.dll是什么東西?steam_api64.dll缺失的多個詳細解決方法

在現代PC游戲領域&#xff0c;Steam無疑是最具影響力的游戲分發和社交平臺之一。它不僅提供了一個龐大的游戲市場&#xff0c;還集成了好友系統、成就系統、云存儲等多種功能&#xff0c;為數百萬玩家提供了便捷的游戲體驗。在這龐大的生態系統中&#xff0c;steam_api64.dll作…

Windows10環境搭建http服務器

我 的 個 人 主 頁&#xff1a;&#x1f449;&#x1f449; 失心瘋的個人主頁 &#x1f448;&#x1f448; 入 門 教 程 推 薦 &#xff1a;&#x1f449;&#x1f449; Python零基礎入門教程合集 &#x1f448;&#x1f448; 虛 擬 環 境 搭 建 &#xff1a;&#x1f449;&…

基于 Wireshark 分析 IP 協議

一、IP 協議 IP&#xff08;Internet Protocol&#xff09;協議是一種網絡層協議&#xff0c;它用于在計算機網絡中實現數據包的傳輸和路由。 IP協議的主要功能有&#xff1a; 1. 數據報格式&#xff1a;IP協議將待傳輸的數據分割成一個個數據包&#xff0c;每個數據包包含有…

[Markdown]是時候該學學使用markdown寫文章了

&#x1f495;&#x1f495;&#x1f495;歡迎各位來到我的博客&#xff0c;今天我們的主題是markdown&#xff0c;你將在這里學習到最全的markdown知識&#x1f495;&#x1f495;&#x1f495; 你還在使用富文本編輯器寫文檔或文章嗎&#xff1f; 你還在用word一點一點地進行…

算法訓練營day29

一、組合 參考鏈接77. 組合 - 力扣&#xff08;LeetCode&#xff09; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Deque; import java.util.List;public class Solution {public List<List<Integer>> combine (int n, int k) …

C語言----斐波那契數列

各位看官們好&#xff0c;當我寫了上一篇博客楊輝三角后&#xff0c;有一些看官叫我講一下斐波那契數列。對于這個大家應該是有了解的。最簡單的規律就是f(n)f(n-2)f(n-1)。就是當前是前兩項之和&#xff0c;然后下標1和0都是1.從第三項開始計算的。那么我們知道規律&#xff0…

選購洗地機有哪些技巧?2024洗地機全面解析,618洗地機綜合對比

洗地機作為人們生活中智能清潔工具的代表&#xff0c;它自帶清/污水箱&#xff0c;不用手洗滾刷&#xff0c;既可以吸塵也可以自動識別并清洗地板上的干濕垃圾和頑固污漬&#xff0c;它以多功能一體化的設計改善了家務清潔的效率和體驗。那么如何在眾多洗地機品牌中&#xff0c…

C#實現簡單音樂文件解析播放——Windows程序設計作業2

1. 作業內容 編寫一個C#程序&#xff0c;要求實現常見音樂文件的播放功能&#xff0c;具體要求如下&#xff1a; ????1). 播放MP3文件&#xff1a; 程序應能夠讀取MP3文件&#xff0c;并播放其中的音頻。 ????2). 播放OGG文件&#xff1a; 應能夠播放ogg文件。 ????…

阿里云Redis創建使用

說明&#xff1a;本文介紹如何使用阿里云Redis&#xff0c;包括開通、連接、使用&#xff1b; 開通 進入官網Redis產品頁&#xff0c;點擊免費試用&#xff08;白嫖&#xff09;&#xff1b; 選擇中間這個&#xff0c;云數據庫Redis版&#xff1b; 開通完成后&#xff0c;可在…

如何在Java項目中使用Spring Boot快速連接達夢數據庫(DM)

前言 在Java開發領域&#xff0c;Spring Boot憑借其簡潔快速的特性成為現代應用開發的首選框架。本文將詳細介紹如何在Spring Boot項目中整合JDBC以快速連接達夢數據庫(DM)&#xff0c;并提供一個簡單的示例來驗證連接是否成功。 一、環境準備與依賴配置 在開始之前&#xf…

零代碼平臺助力中國石化江蘇油田實現高效評價體系

概述&#xff1a; 中國石化集團江蘇石油勘探局有限公司面臨著評價體系依賴人工處理數據、計算繁瑣且容易出錯的挑戰。為解決這一問題&#xff0c;他們決定借助零代碼平臺明道云開發江蘇油田高質量發展經濟指標評價系統。該系統旨在實現原始數據批量導入與在線管理、權重及評分…

QT設計模式:建造者模式

基本概念 建造者模式是一種創建型設計模式&#xff0c;它允許你創建復雜對象的過程獨立于該對象的組成部分以及它們的組裝方式。這樣可以構造出不同的對象表示。 在建造者模式中&#xff0c;將創建對象的過程和對象的表示分離&#xff0c;通過一步步的構建&#xff0c;可以得…

FFmpeg常用API與示例(四)——過濾器實戰

1.filter 在多媒體處理中&#xff0c;filter 的意思是被編碼到輸出文件之前用來修改輸入文件內容的一個軟件工具。如&#xff1a;視頻翻轉&#xff0c;旋轉&#xff0c;縮放等。 語法&#xff1a;[input_link_label1]… filter_nameparameters [output_link_label1]… 1、視…

C++中調用python函數(VS2017+WIN10+Anaconda虛擬環境)

1.利用VS創建C空項目 step1 文件——新建——項目 step2 Visual C—— Windows桌面——Windows桌面向導 step3 選擇空項目 step4 源文件——新建項——添加 step5 Visual C——C文件&#xff08;.cpp&#xff09; 2.配置環境 Step1. 更換成Release與X64 Step2. 打開項目屬性&…

文本提取新技能:學會按行數批量提取,輕松應對各種需求

在數字化時代&#xff0c;文本處理成為我們日常生活和工作中不可或缺的一部分。無論是從網頁、文檔還是數據庫中提取信息&#xff0c;文本提取技能都顯得尤為重要。而按行數批量提取文本內容&#xff0c;更是文本處理中的一項高效且實用的技能。本文將介紹辦公提效工具如何按行…

在Spring Boot應用安裝SSL證書

目錄 前提條件 步驟一&#xff1a;下載SSL證書 步驟二&#xff1a;在Spring Boot安裝SSL證書 步驟三&#xff1a;驗證SSL證書是否安裝成功 前提條件 已通過數字證書管理服務控制臺簽發證書SSL證書綁定的域名已完成DNS解析&#xff0c;即您的域名與主機IP地址相互映射已在W…