主頁 > .NET開發 > 從零搭建一個IdentityServer——聊聊Asp.net core中的身份驗證與授權

從零搭建一個IdentityServer——聊聊Asp.net core中的身份驗證與授權

2021-02-04 06:10:27 .NET開發

OpenIDConnect是一個身份驗證服務,而Oauth2.0是一個授權框架,在前面幾篇文章里通過IdentityServer4實作了基于Oauth2.0的客戶端證書(Client_Credentials)、用戶名密碼(Password)的授權流程,同時也實作OpenIDConnect的授權碼(Authorization Code)、隱式流程(Implicit)的身份驗證,   ???啥?一會兒是授權一會兒是身份驗證,身份驗證與授權傻傻分不清楚??本文就來聊一聊Asp.net core中的身份驗證與授權,   本文主要內容有:
  • 身份驗證與授權
  • Asp.net core中的身份驗證與授權
  • Asp.net core身份驗證及授權的基本原理
    • Scheme與身份驗證處理器
    • 三個方法Authenticate、Challenge、Forbid
    • 兩個中間件AuthenticationMiddleware、AuthorizationMiddleware
    • 三個物件HttpContext、ClaimsIdentity、AuthenticationProperties
  • Signin與身份資訊載體
  • 自主登錄與外部登錄
  • Asp.net core身份驗證及授權流程
  • Asp.net core中的授權
  • 小結

身份驗證與授權

  以前寫過一篇asp.net identity的文章(https://www.cnblogs.com/selimsong/p/7828326.html)已經提到過身份驗證與授權的概念,簡單來說身份驗證就是“是誰”的問題,而授權就是“能不能”的問題,一般來說首先需要知道“是誰”,然后再判斷“能不能”,   這里舉個生活中常見的小栗子,鎖是門用來保護門內財產的工具,而隨著科技發展現在有了指紋鎖,指紋鎖的特征是它既可以通過指紋來開鎖,也可以通過鑰匙開鎖,對于指紋開鎖時首先需要錄入指紋并指定一個指紋身份,比如保姆阿姨,首先需要的就是給她錄入指紋,然后允許該指紋在上午6點至晚上10點可以開門,那么最終保姆阿姨在開門時,授權識別指紋,通過指紋匹配到或者說知道是保姆,這里就是身份驗證,如果陌生人進行指紋匹配那么將匹配不到任何身份,但是能否開門還得根據設定的規則,那就是開門時間是否在規定的時間范圍內,滿足條件才能開門,這就是授權,   當然在開門這個問題上還有一個Bug,那就是鑰匙,只要擁有鑰匙,不管是誰都能開門,獲得鑰匙就是獲得授權,   在軟體系統中通常使用的用戶名密碼登錄實際上就是身份驗證功能,用戶登錄后系統就記住這一狀態,后續訪問系統時系統就知道“是誰”在訪問系統,然后因為已經知道是誰,那么就可以根據具體訪問條件來判斷用戶“能不能”訪問資源,這就是授權,

Asp.net core中的身份驗證與授權

  首先需要再次明確一下Asp.net core是一個Web框架,它本身就具有一些特性,這其中就包括了身份驗證和授權,   在Asp.net core中的身份驗證和授權是通過中間件完成的,而把一個中間件添加到asp.net core的應用程式中一般只需要兩個步驟,第一是對相關中間件所需引數及服務進行配置,第二就是將相應的中間件添加到請求管道中即可,   下圖為基于OpenIDConnect客戶端程式的身份驗證配置:      下圖為基于OpenIDConnect客戶端程式的身份驗證及授權中間件配置:      以上代碼并沒有額外的配置授權策略,但是可以通過Authorize特性來提供最基礎的授權(授權通過身份驗證的用戶),另外需要注意的是Authorize特性是需要搭配Authorization中間件來使用的,如下圖所示:      另外基于Identity組件的身份驗證代碼中沒有出現AddAuthentication及AddCookie方法,而是通過AddDefaultIdentity就可以完成身份驗證,是因為AddDefaultIdentity方法中包含了相關方法呼叫:      AddDefaultIndeity方法代碼:   完成配置后就可以在應用程式中使用身份驗證及授權功能了,   關于asp.net core官方提供的身份驗證方式,我們可以直接看看GitHub上的代碼:      從圖中可以看到有基于Cookie、Jwt Bearer、Oauth、OpenIdConnect也有基于Facebook、Google、MicrosoftAccount、Twitter的,如果非官方的話應該還能找到基于微信、支付寶等賬號的登錄開源庫,   總的來說asp.net core的身份驗證可以支持現有的大部分常用方式或協議,同時也支持第三方的賬戶登錄,

Asp.net core身份驗證及授權的基本原理

Scheme與身份驗證處理器

  Scheme和處理器可以簡單的理解為一個鍵值對,處理器是用于實際處理身份驗證邏輯的代碼,Scheme就是這個處理器的標識,通過Scheme可以直接獲取到相應的處理器,然后通過處理器來完成身份驗證,   Scheme是一個重要的概念,因為在asp.net core中它可以添加多個身份驗證處理器,在Asp.net版本中,或者準確來講Owin中我們就提到過一個多重身份驗證的概念(ASP.NET沒有魔法——ASP.NET Identity 的“多重”身份驗證)實際上也就是在一個應用里面添加了多個身份驗證處理器,換句話說就是一個應用程式支持多種身份驗證(登錄)方式,asp.net core中管理多個身份驗證處理器的核心就是基于Scheme,還記得本文上面oidc驗證添加的服務配置代碼嗎,      在這段代碼中設定了身份驗證的默認Scheme以及默認ChallengeScheme,關于Scheme的作用請往下看,   注:asp.net 與asp.net core中的身份驗證機制有共同點也有區別,總體來說asp.net core基于scheme的身份驗證管理機制邏輯上和性能上會更好(畢竟是最新的產物),   關于身份驗證處理器,它實際上就是一個實作IAuthenticationHandler介面的型別,它提供了身份驗證所需的具體實作邏輯:   

三個方法Authenticate、Challenge、Forbid

  這三個方法是asp.net core身份驗證/授權中的基礎,它們分別代表身份驗證、質疑和禁止,每一個身份驗證處理器都需要實作這三個方法,下面簡單介紹一下這三個方法:   Authenticate:
  • 身份驗證呼叫和核心邏輯,換句話就是證明“是誰”的方法,
  • 擬人化來說就是檢查身份證同時與持有人是否匹配的程序,
  • 在程式中就是檢查cookie、jwt token、id token等是否有效,以及資訊載體中標記的用戶“是誰”
  Challenge:
  • 可翻譯為“懷疑/質疑”,實際上就是身份驗證沒有成功后呼叫的方法,
  • 擬人化來說就是“我”不知道你“是誰”,但“我”需要知道,所以“我”會問“你是誰?把你的身份證給我看一下?”
  • 在程式中一般的程序就是重定向到登錄頁面,通過登錄方式告訴系統“是誰”,對于Api一類沒有UI的程式時,就回傳401狀態碼告知未通過身份驗證,
  Forbid:
  • 這個方法用于授權,授權失敗時呼叫該方法,
  • 這個方法相對簡單,當程式存在UI時,通過UI告知用戶無權限禁止訪問即可,對于Api一類沒有UI的程式時,通過回傳403狀態碼告知無權限,

兩個中間件AuthenticationMiddleware、AuthorizationMiddleware

  身份驗證中間件(AuthenticationMiddleware),只做三件事:   1. 處理身份驗證請求,如oidc的由身份驗證服務器完成id_token生成跳轉的/signi-oidc,   2. 處理默認scheme的身份驗證流程,   3. 如果身份驗證通過后將驗證結果的主體資訊(Principal)放到HttpContext中,   主要代碼如下圖(參考:https://github.com/dotnet/aspnetcore/blob/main/src/Security/Authentication/Core/src/AuthenticationMiddleware.cs):      授權中間件(AuthorizationMiddleware)主要是通過一系列終結點授權資訊獲取、執行后根據授權執行結果來決定是challenge、forbidden還是擁有權限可進入資源訪問(參考:  https://github.com/dotnet/aspnetcore/blob/main/src/Security/Authorization/Policy/src/AuthorizationMiddleware.cs  https://github.com/dotnet/aspnetcore/blob/main/src/Security/Authorization/Policy/src/AuthorizationMiddlewareResultHandler.cs):      注:如果所訪問的資源沒有授權相關的限制,那么請求將跳過授權步驟直接往下訪問,

三個物件HttpContext、ClaimsIdentity、AuthenticationProperties

  首先我們來看看ClaimsIdentity,它實際上是一組Claim的集合,每個Claim代表用戶身份的一個屬性的鍵值對,一組Claim可以表示某一方面的用戶資訊特性,除此之外它還包含是否通過驗證(IsAuthenticated)以及驗證方式(AuthenticationType)等資訊,   下圖為通過oidc身份驗證的ClaimsIdentity資訊,HttpConext物件中包含的User是ClaimsPrincipal(宣告的主體),一個主體里面包含多個ClaimsIdentity資訊:      這里可以這么理解這些物件:   1. 我們每個人都有身份證、護照、戶口冊、駕照等可以證明我們身份的東西,這相當于一個ClaimsPrincipal可以擁有多個ClaimsIdentity,   2. 身份證上面有姓名、身份證號等屬性,相當于一個ClaimsIdentity包含多個Claim,   3. 關于Claim它代表一個用戶資訊屬性,并且一些屬性名稱是有相關定義的,具體參考:https://docs.microsoft.com/en-us/dotnet/api/system.security.claims.claimtypes?view=net-5.0,   4. 每個身份證明它的識別方法不一樣,比如身份證可以通過身份證識別器識別、戶口冊可以在公安局識別,這個相當于每個ClaimsIdentity中的AuthenticationType,     AuthenticationProperties:它是一個用來存盤身份驗證會話資料的字典,oidc流程中IdentityServer回傳的Id_token及access_token等資訊就是存盤到AuthenticationProperties中,     HttpContext:Http背景關系物件,是整個請求的核心,包含了Http請求及回應的所有內容,但是在身份驗證/授權方面,它有另一個角色——身份驗證服務代理,通過HttpContext我們可以呼叫身份驗證服務的相關方法,包括身份驗證和授權中間件的Challenge等方法呼叫都是通過HttpContext完成的,   下圖為HttpContext在Authentication命名空間下的拓展方法定義:      下圖為IAuthenticationService的方法定義,HttpContext通過容器獲取IAuthenticationService的實體進行呼叫,而IAuthenticationService最終實際上呼叫的是指定或默認身份驗證處理器的相關方法:   

Signin與身份資訊載體

  前面文章詳細講解了身份驗證的相關細節,但唯獨沒說的就是登錄,登錄到底是做了什么事情?在了解登錄之前我們先來了解一個概念“身份資訊載體”,其實也就字面意思,承載身份資訊的物體,在現實生活中我們的身份資訊載體是“身份證”等等實際物品,而在資訊系統中資訊載體就是一段資料,這段資料為了能讓相關程式或者廣大程式所理解,它應該按照具體的協議來創建,資訊系統中常用的身份資訊載體有Cookie以及Jwt(Json web token),   Cookie:   我們都知道http是一個無狀態協議,但是大部分時候我們需要它“有”狀態,Cookie作為一專案覽器資料存盤技術,它經常用于存盤一些狀態資訊,用于下一次發起請求的時候服務器能夠了解當前請求的狀態,所以Cookie非常適合作為身份資訊載體,當然asp.net core的基于Cookie身份驗證是這樣做的,將用戶資訊(ClaimsIdentity)加密后存盤到Cookie中,下次從Cookie中獲取資料,解密后獲得用戶資訊并完成身份驗證,   Jwt:   Jwt是一種基于Json的安全資訊傳輸標準,Jwt因為帶有數字簽名的,可以保證資料完整性,就想我們的身份證一樣不能偽造,所以也很適合作為身份資訊載體,     Cookie和Jwt各有特點,可適用于不同的應用場景,如Cookie它本身有域特性,現在的單頁應用程式它會存在跨域問題,而Jwt雖然能保證資料完整,但是它本身不是加密的(但是傳輸程序可以加密,并且生產一般必須加密,如https),所以Jwt中的身份資訊很容易泄漏,所以它比較適合更封閉的客戶端,如服務端與服務端通訊、手機App等,     現在我們再回來聊登錄,登錄實際上就是將身份資訊寫到身份資訊載體的程序,基于Cookie的就寫Cookie,基于Jwt的就頒發Jwt,但是需要注意的是一般jwt由第三方身份驗證服務器頒發,所以應用程式本身是不需要關注的,所以這里主要講講基于Cookie的登錄,   下面我們做一個基于Cookie登錄的小實驗,首先做一個簡單的基于Identity的登錄功能:      設定斷點后,直接訪問登錄頁面進行登錄,在登錄資訊提交后我們可以看到User資訊是空的:      登錄之后仍然沒有用戶資訊:      但是在ResponseHeader的HeaderSetCookie資訊中我們找到了如下資訊:   看到它即將寫入cookie中帶有它創建的身份資訊載體,這個就是登錄生成身份資訊載體的程序,至于登陸后即可訪問保護內容,是因為登錄完成后做了跳轉,跳轉后將攜帶身份資訊發起請求后既可以完成身份驗證,從而可以訪問受保護內容,   注:Identity提供的登錄功能最終也是通過HttpContext的拓展方法通過IAuthenticationService來完成的,具體可參考相關原始碼,這里不在贅述,   https://github.com/dotnet/aspnetcore/blob/main/src/Http/Authentication.Core/src/AuthenticationService.cs   https://github.com/dotnet/aspnetcore/blob/main/src/Security/Authentication/Cookies/src/CookieAuthenticationHandler.cs

自主登錄與外部登錄

  自主登錄指的是應用程式本身提供了用戶身份核對(用戶名+密碼登錄),然后擁有用戶資訊自主權(應用程式保存了與用戶相關的資訊),最后根據用戶資訊來生成用戶資訊載體的登錄方式,如Asp.net core Identity提供的就是一種自主登錄方式,   外部登錄指的是由第三方程式來對用戶身份核對,并提供相關用戶資訊交由程式本身來生成用戶資訊載體的,或者直接由第三方程式生成用戶資訊載體的方式,   如本系列文章介紹的oidc的身份驗證就是由IdentityServer提供用戶身份核對并提供用戶資訊(UserInfo EndPoint),然后交由客戶端程式來生成身份資訊載體Cookie,   而如果通過IdentityServer直接通過Oauth2.0流程獲得Access Token的方式就相當于由第三方程式生成用戶資訊載體,客戶端直接驗證用戶資訊載體即可完成后續的身份驗證,

Asp.net core身份驗證及授權流程

  前面內容詳細介紹了Asp.net core身份驗證相關的一些基礎原理,下面就通過一個流程圖來介紹一下完整的身份驗證和授權流程:      從圖中我們可以找到3個主體分別是:瀏覽器、Asp.net core應用程式以及第三方驗證服務,   整個流程的開始可能是通過訪問受保護資源、自主登錄系統或者外部登錄系統開始,但是登錄的目的在于訪問受保護資源,下面就簡單對訪問受保護資源流程進行梳理:   1. 瀏覽器發起受保護資源訪問請求(沒有Cookie).   2. 服務器對請求進行身份驗證,因為沒有Cookie回傳一個失敗結果,   3. 因為驗證結果為失敗,所以沒有ClamsIdentity資訊,賦值到HttpContext.User也為空,   4. 進行授權判斷,因為沒有經過身份驗證,所以呼叫質疑操作(Challenge),由默認的ChallengeScheme決定是自主登錄還是外部登錄,   5. 如果是自主登錄,那么跳轉到應用登錄頁面完成登錄,并根據用戶資訊生成ClaimsIdentity,   5. 如果是外部登錄,那么跳轉到第三方登錄頁面完成登錄,并回到自主應用的回呼地址對第三方回傳的code、id_token及access_token進行處理,并獲取用戶資訊,根據獲取的用戶資訊生成ClaimsIdentity,   6. 系統將ClaimsIdentity資訊生成身份資訊載體(Cookie)并重定向回之前訪問的資源,   7. 重定向后攜帶身份資訊載體訪問受保護資源,如果用戶有權限,那么可訪問資源,如果沒有權限回傳403禁止訪問,     小提示:為什么asp.net core identity生成的UI代碼中,外部登錄執行的核心代碼為ChallegeResult + (provider 和returnUrl)?    

Asp.net core中的授權

  前面詳細介紹了Asp.net core中的身份驗證,授權僅僅是其中的一環來幫助完成身份驗證,那么Asp.net core中提供了哪些授權機制或者說要如何進行授權呢?   Asp.net core及Identity組件提供了簡單的(只要通過身份驗證)、基于角色的、基于宣告(Claim)的、基于策略的授權機制,具體使用方式參考檔案:https://docs.microsoft.com/en-us/aspnet/core/security/authorization/introduction?view=aspnetcore-5.0   另外還給了一個如何實作資料增刪改權限控制的例子:   https://docs.microsoft.com/en-us/aspnet/core/security/authorization/secure-data?view=aspnetcore-5.0   上面這個例子告訴我們授權機制不僅僅局限于授權特性和中間件,我們可以把授權機制融入到我們的業務邏輯中,

小結

  本篇文章從Asp.Net core介紹了身份驗證和授權的基本概念和原理,通過流程圖的方式展現了Asp.net core身份驗證和授權的流程,最后簡單介紹了授權的相關機制,   現在我們回到文章開頭問的問題為什么IdentityServer4提供的功能中一會兒是身份驗證,一會兒是授權??   這個問題需要根據主體來看,首先我們看Oauth2.0,它的最終結果是一個Jwt的Bearer Token,這相當于給了你一把鑰匙,使用這個鑰匙你可以打開指定的門,所以它是一個授權,   然后來看看OIDC的授權碼流程,它除了Access Token外實際上關鍵的是Id_token,證實了用戶的身份,這相當于告訴你,用戶是保姆阿姨,解決了“是誰”的問題,所以是身份驗證,知道了是誰,至于開不開門,那是你(客戶端程式)的授權問題,   最后來看看Asp.net core應用程式,在Asp.net core應用程式中不存在獨立的授權,換句話就是沒法單獨使用授權功能,需要身份驗證和授權功能聯合使用,比如Oauth給了一把鑰匙,但是Asp.net core仍要對鑰匙進行驗證,看清楚鑰匙上貼了張三的名字,但很有可能這把鑰匙是李四拿著,   參考: https://docs.microsoft.com/en-us/aspnet/core/security/authentication/?view=aspnetcore-5.0 https://docs.microsoft.com/en-us/aspnet/core/security/authorization/introduction?view=aspnetcore-5.0 以及文章中涉及的相關源代碼 本文地址:https://www.cnblogs.com/selimsong/p/14367624.html 從零搭建一個IdentityServer——目錄(更新中...)

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/256147.html

標籤:.NET技术

上一篇:Dotnet的區域函式和委托的對比

下一篇:【分享】C# 位元組幫助類 ByteHelper

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • WebAPI簡介

    Web體系結構: 有三個核心:資源(resource),URL(統一資源識別符號)和表示 他們的關系是這樣的:一個資源由一個URL進行標識,HTTP客戶端使用URL定位資源,表示是從資源回傳資料,媒體型別是資源回傳的資料格式。 接下來我們說下HTTP. HTTP協議的系統是一種無狀態的方式,使用請求/ ......

    uj5u.com 2020-09-09 22:07:47 more
  • asp.net core 3.1 入口:Program.cs中的Main函式

    本文分析Program.cs 中Main()函式中代碼的運行順序分析asp.net core程式的啟動,重點不是剖析原始碼,而是理清程式開始時執行的順序。到呼叫了哪些實體,哪些法方。asp.net core 3.1 的程式入口在專案Program.cs檔案里,如下。ususing System; us ......

    uj5u.com 2020-09-09 22:07:49 more
  • asp.net網站作為websocket服務端的應用該如何寫

    最近被websocket的一個問題困擾了很久,有一個需求是在web網站中搭建websocket服務。客戶端通過網頁與服務器建立連接,然后服務器根據ip給客戶端網頁發送資訊。 其實,這個需求并不難,只是剛開始對websocket的內容不太了解。上網搜索了一下,有通過asp.net core 實作的、有 ......

    uj5u.com 2020-09-09 22:08:02 more
  • ASP.NET 開源匯入匯出庫Magicodes.IE Docker中使用

    Magicodes.IE在Docker中使用 更新歷史 2019.02.13 【Nuget】版本更新到2.0.2 【匯入】修復單列匯入的Bug,單元測驗“OneColumnImporter_Test”。問題見(https://github.com/dotnetcore/Magicodes.IE/is ......

    uj5u.com 2020-09-09 22:08:05 more
  • 在webform中使用ajax

    如果你用過Asp.net webform, 說明你也算是.NET 開發的老兵了。WEBform應該是2011 2013左右,當時還用visual studio 2005、 visual studio 2008。后來基本都用的是MVC。 如果是新開發的專案,估計沒人會用webform技術。但是有些舊版 ......

    uj5u.com 2020-09-09 22:08:50 more
  • iis添加asp.net網站,訪問提示:由于擴展配置問題而無法提供您請求的

    今天在iis服務器配置asp.net網站,遇到一個問題,記錄一下: 問題:由于擴展配置問題而無法提供您請求的頁面。如果該頁面是腳本,請添加處理程式。如果應下載檔案,請添加 MIME 映射。 WindowServer2012服務器,添加角色安裝完.netframework和iis之后,運行aspx頁面 ......

    uj5u.com 2020-09-09 22:10:00 more
  • WebAPI-處理架構

    帶著問題去思考,大家好! 問題1:HTTP請求和回傳相應的HTTP回應資訊之間發生了什么? 1:首先是最底層,托管層,位于WebAPI和底層HTTP堆疊之間 2:其次是 訊息處理程式管道層,這里比如日志和快取。OWIN的參考是將訊息處理程式管道的一些功能下移到堆疊下端的OWIN中間件了。 3:控制器處理 ......

    uj5u.com 2020-09-09 22:11:13 more
  • 微信門戶開發框架-使用指導說明書

    微信門戶應用管理系統,采用基于 MVC + Bootstrap + Ajax + Enterprise Library的技術路線,界面層采用Boostrap + Metronic組合的前端框架,資料訪問層支持Oracle、SQLServer、MySQL、PostgreSQL等資料庫。框架以MVC5,... ......

    uj5u.com 2020-09-09 22:15:18 more
  • WebAPI-HTTP編程模型

    帶著問題去思考,大家好!它是什么?它包含什么?它能干什么? 訊息 HTTP編程模型的核心就是訊息抽象,表示為:HttPRequestMessage,HttpResponseMessage.用于客戶端和服務端之間交換請求和回應訊息。 HttpMethod類包含了一組靜態屬性: private stat ......

    uj5u.com 2020-09-09 22:15:23 more
  • 部署WebApi隨筆

    一、跨域 NuGet參考Microsoft.AspNet.WebApi.Cors WebApiConfig.cs中配置: // Web API 配置和服務 config.EnableCors(new EnableCorsAttribute("*", "*", "*")); 二、清除默認回傳XML格式 ......

    uj5u.com 2020-09-09 22:15:48 more
最新发布
  • C#多執行緒學習(二) 如何操縱一個執行緒

    <a href="https://www.cnblogs.com/x-zhi/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2943582/20220801082530.png" alt="" /></...

    uj5u.com 2023-04-19 09:17:20 more
  • C#多執行緒學習(二) 如何操縱一個執行緒

    C#多執行緒學習(二) 如何操縱一個執行緒 執行緒學習第一篇:C#多執行緒學習(一) 多執行緒的相關概念 下面我們就動手來創建一個執行緒,使用Thread類創建執行緒時,只需提供執行緒入口即可。(執行緒入口使程式知道該讓這個執行緒干什么事) 在C#中,執行緒入口是通過ThreadStart代理(delegate)來提供的 ......

    uj5u.com 2023-04-19 09:16:49 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    <a href="https://www.cnblogs.com/huangxincheng/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/214741/20200614104537.png" alt="" /&g...

    uj5u.com 2023-04-18 08:39:04 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    一:背景 1. 講故事 前段時間協助訓練營里的一位朋友分析了一個程式卡死的問題,回過頭來看這個案例比較經典,這篇稍微整理一下供后來者少踩坑吧。 二:WinDbg 分析 1. 為什么會卡死 因為是表單程式,理所當然就是看主執行緒此時正在做什么? 可以用 ~0s ; k 看一下便知。 0:000> k # ......

    uj5u.com 2023-04-18 08:33:10 more
  • SignalR, No Connection with that ID,IIS

    <a href="https://www.cnblogs.com/smartstar/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/u36196.jpg" alt="" /></a>...

    uj5u.com 2023-03-30 17:21:52 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:15:33 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:13:31 more
  • C#遍歷指定檔案夾中所有檔案的3種方法

    <a href="https://www.cnblogs.com/xbhp/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/957602/20230310105611.png" alt="" /></a&...

    uj5u.com 2023-03-27 14:46:55 more
  • C#/VB.NET:如何將PDF轉為PDF/A

    <a href="https://www.cnblogs.com/Carina-baby/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2859233/20220427162558.png" alt="" />...

    uj5u.com 2023-03-27 14:46:35 more
  • 武裝你的WEBAPI-OData聚合查詢

    <a href="https://www.cnblogs.com/podolski/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/616093/20140323000327.png" alt="" /><...

    uj5u.com 2023-03-27 14:46:16 more