網站首頁 編程語言 正文
一、WebApi中為什么需要身份認證
我們在使用WebApi的時候,都是通過URL去獲取數據。也就是說,任何人只要知道了URL地址,就能隨意的訪問后臺的服務接口,就可以訪問或者修改數據庫數據了,這樣就會導致很嚴重的后果。
1、我們不加身份認證,匿名用戶可以直接通過url隨意訪問接口:
2、增加了身份認證之后,只有帶了票據的請求才能訪問對應的接口。
二、常見的認證方式
WebApi中常見的認證方式有如下幾種:
- FORM身份驗證
- 集成WINDOWS驗證
- Basic基礎認證
- Digest摘要認證
三、Basic基礎認證
Basic基礎認證原理
Basic認證的基本原理就是加密用戶信息生成Ticket,每次請求后端API接口的時候把生成的Ticket信息加到http請求的頭部傳給后端進行驗證。具體步驟如下:
- 1、登錄的時候驗證用戶名和密碼,如果驗證通過,則將用戶名和密碼按照一定的規則生成加密后的票據信息Ticket,然后將Ticket傳遞到前端。
- 2、如果登錄成功,前端定義一個全局的變量接收API接口返回的Ticket信息。
- 3、前端界面再次發起ajax請求后端API接口的時候,將Ticket信息加入到HTTP請求的Head里面,將Ticket信息隨著http請求一起發送到后端API接口。
- 4、在后端的WebApi服務中定義一個類,該類繼承自AuthorizeAttribute類,然后重新父類里面的OnAuthorization方法,在OnAuthorization方法里面,通過actionContext參數取得http請求的Head,從Head里面可以獲取前端傳遞過來的Ticket信息。將Ticket解密得到用戶名和密碼,然后驗證用戶名和密碼是否正確。如果正確,表示驗證通過。如果不正確,則返回401未授權的錯誤。
四、Basic基礎認證示例代碼
假設我們要訪問Users控制器的Get接口,該接口方法返回int類型的List集合。
1、登錄的API接口
using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Web.Http; using System.Web.Security; using WebApiBasicAuthorize.CustomerAttribute; using WebApiBasicAuthorize.Entity; namespace WebApiBasicAuthorize.Controllers { [BasicAuthorize] public class UsersController : ApiController { ////// 允許匿名登錄 /// /// /// ///[AllowAnonymous] [HttpGet] public IHttpActionResult Login(string account,string password) { ReturnValueEntity entity = new ReturnValueEntity(); // 真實生產環境中要去數據庫校驗account和password if (account.ToUpper().Trim().Equals("ADMIN") && password.Trim().Equals("123456")) { FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(0, account, DateTime.Now, DateTime.Now.AddHours(1), true, string.Format("{0}&{1}", account, password), FormsAuthentication.FormsCookiePath); var result = new { Result = true, Ticket = FormsAuthentication.Encrypt(ticket) }; entity.Result = true; entity.Ticket = FormsAuthentication.Encrypt(ticket); } else { entity.Result = false; entity.Ticket = ""; } return Json (entity); } [HttpGet] public IHttpActionResult Get() { List list = new List (); list.Add(1); list.Add(2); list.Add(3); list.Add(4); list.Add(5); return Json >(list); } } }
在Login方法上面添加 [AllowAnonymous]特性,表示允許匿名登錄。
2、基礎認證接口
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Http; using System.Web.Http.Controllers; using System.Web.Security; namespace WebApiBasicAuthorize.CustomerAttribute { ////// 自定義特性繼承自AuthorizeAttribute /// public class BasicAuthorizeAttribute:AuthorizeAttribute { public override void OnAuthorization(HttpActionContext actionContext) { // 從當前http請求Request對象的頭部信息里面獲取Authorization屬性 var authorization = actionContext.Request.Headers.Authorization; // 判斷控制器獲取action方法上面是否有AllowAnonymousAttribute特性,如果有,則允許匿名登錄 if (actionContext.ActionDescriptor.GetCustomAttributes(true).Count != 0 || actionContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes (true).Count != 0) { base.OnAuthorization(actionContext); } else if (authorization != null && authorization.Parameter != null) { // 驗證用戶邏輯 if (ValidateTicket(authorization.Parameter)) { // 驗證通過 base.IsAuthorized(actionContext); } else { this.HandleUnauthorizedRequest(actionContext); } } else { // 返回401沒有授權的狀態碼 this.HandleUnauthorizedRequest(actionContext); } } /// /// 驗證Ticket信息 /// /// ///private bool ValidateTicket(string encryptTicket) { // 解密Ticket var strTicket = FormsAuthentication.Decrypt(encryptTicket).UserData; // 從Ticket里面獲取用戶名和密碼 int index = strTicket.IndexOf("&"); //string strUser=strTicket string[] array = strTicket.Split('&'); string strUser = array[0]; string strPwd = array[1]; // 真實生產環境中應該用解密的用戶名和密碼去數據庫驗證,這里為了演示方便 // 假定用戶名是Admin,密碼是123456 if(strUser.Equals("Admin")&&strPwd.Equals("123456")) { return true; } else { return false; } } } }
3、前端代碼
權限認證
這里需要說明的是,我們在發送ajax請求之前,通過XHR.setRequestHeader('Authorization', 'BasicAuth ' + Ticket); 這句向http請求的Head里面添加Ticket信息。
通過上面的幾步就可以達到Basic認證的效果了。
注意:后端的WebApi接口要配置允許跨域訪問。
4、優化
每增加一個控制器,都需要在相應的控制器上面加[BasicAuthorize]特性,可以定義一個公共的控制器父類,該父類繼承自ApiController,然后其他控制器繼承該父類。
原文鏈接:https://www.cnblogs.com/dotnet261010/p/10059938.html
相關推薦
- 2022-04-25 C++特殊成員函數以及其生成機制詳解_C 語言
- 2022-12-10 C++如何將vector數字寫入到txt文件中_C 語言
- 2022-11-12 PostgreSQL邏輯復制解密原理解析_PostgreSQL
- 2022-05-23 ZooKeeper分布式協調服務設計核心概念及安裝配置_zabbix
- 2022-06-12 Android?Flutter利用貝塞爾曲線畫一個小海豚_Android
- 2022-05-01 Python?Pandas讀取Excel日期數據的異常處理方法_python
- 2023-03-20 C#如何將DLL打包到程序中_C#教程
- 2022-08-29 Python使用re模塊實現正則表達式操作指南_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支