更新 : html
id4 使用這個 DbContext 哦程序員
dotnet ef migrations add identity-server-init --context PersistedGrantDbContext
參考web
https://docs.microsoft.com/en-us/azure/key-vault/key-vault-use-from-web-application#authenticate-with-a-certificate-instead-of-a-client-secret
https://docs.microsoft.com/en-us/powershell/module/pkiclient/new-selfsignedcertificate?view=win10-ps
https://identityserver4.readthedocs.io/en/release/topics/crypto.html#signing-key-rollover
https://mcguirev10.com/2017/12/23/easy-configuration-sharing-with-azure-key-vault.html
https://mcguirev10.com/2018/01/10/storing-certificates-azure-keyvault.html
https://mcguirev10.com/2018/01/04/localhost-ssl-identityserver-certificates.htmlshell
identity server 4 (簡稱 ids) 是一個作認證和受權的小工具. 後端
asp.net core 自帶的 identity 雖然蠻牛的,可是基於 cookies 不適合手機開發。api
與其說手機開發,乾脆點事不適合先後端分離的開發模式. 服務器
先後端分離是作 web application 或 mobile application 時經常使用的手法. cookie
顯然 asp.net core identity 目前仍是偏向後端輸出 html 的方案,而不是基於 Web Api.app
若是開發 Web Application 一般項目會比較複雜,先後端分離,Web Api 就須要 access token (Json Web Token)asp.net
這類的方式, 還有受權也是同樣, oauth 2.0 也是常常會用到的.
ids 除了支持 oauth 2.0 還支持 OpenId Connect
咱們從前都是用 oauth 2.0 來幹 Open Id 作的事情,因此忽然多了一個東西我開始的時候是以爲很奇怪的。
慢慢明白, oauth 是用於受權, open id 則是認證.
認證之後,咱們一般是須要識別這我的的,好比 username profile claim 等等.
而 oauth 受權只是給你一個 access token 有能力去操做一些東西,可是並無直接告訴你用戶。
而從前咱們是經過 access token + getUserProfile 這類的 api 才完成了如今 open id 作的事情。
因此有了 open id 職責就劃分的更好了,更規範了。
上面說的整套 ids 都作好了, 但我目前的需求其實也只是要支持 token based 而已. 還不須要 oauth 2.0 或 openid
可是自帶的 identity 目前又還不支持 token based, net core 2.2 貌似會有一箇中間版本, 把 identity 增強支持 token based.
因此呢,我只能暫時拿 ids 大材小用了.
原本也考慮要本身寫一個 JWT 的機制,可是後來想一想這樣很傻,畢竟我是寫業務的程序員,怎麼還要幹這麼技術的事情呢... 對吧.
對比 identity cookies based, token based 有 2 點很不一樣,
1. 刷新機制.
cookies based 咱們能夠經過每一次請求,服務器 response 來讓 cookie 保存新鮮. 可是基於 header 的 token based 徹底就沒有辦法作到這點。
因此必須弄多一個 refresh token 出來.
2. 加密機制
token based 一般是用 JWT 它是用非對稱加密, 而 cookie based 一般是使用對稱加密.
identity 內部使用了 asp.net core data protection 來加密
ids 則須要咱們去弄一個 self signed certificate.
ids 的過程是這樣的。
有 3 個角色, 認證服務器(登入的地方), 資源服務器 (通常的 web api 站點), 客戶端 (用戶遊覽器)
用戶想訪問受保護的資源就必須先經過認證服務器登入和受權 (scope, claim 等),oauth 2.0, 4 中方式均可以.
獲取到 token 以後訪問資源服務器, 資源服務器會去認證服務器獲取 document (裏面會有認證服務器的資訊,好比 endpoint, 公鑰等等), 而後資源服務器發起請求.
整套都是頗有規範的.
固然你要把認證服務器和資源服務器放一塊兒也是能夠的, 可是走的流程是同樣的.
Self signed certificate
參考
https://docs.microsoft.com/en-us/azure/key-vault/key-vault-use-from-web-application#authenticate-with-a-certificate-instead-of-a-client-secret
https://docs.microsoft.com/en-us/powershell/module/pkiclient/new-selfsignedcertificate?view=win10-ps
https://identityserver4.readthedocs.io/en/release/topics/crypto.html#signing-key-rollover
https://mcguirev10.com/2017/12/23/easy-configuration-sharing-with-azure-key-vault.html
https://mcguirev10.com/2018/01/10/storing-certificates-azure-keyvault.html
https://mcguirev10.com/2018/01/04/localhost-ssl-identityserver-certificates.html
// start -> Windows PowerShell -> run as admin
$PfxFilePath = "c:\keatkeat\self-signed-certificate\bestway.pfx"
$CerFilePath = "c:\keatkeat\self-signed-certificate\bestway.cer"
$DNSName = "localhost"
$Password ="P@ssword2012"
$friendlyName = "bestway"
$SecStringPw = ConvertTo-SecureString -String $Password -Force -AsPlainText
$Cert = New-SelfSignedCertificate -KeyFriendlyName $friendlyName -FriendlyName $friendlyName -DnsName $DNSName -CertStoreLocation "cert:\LocalMachine\My" -NotAfter $((Get-Date).AddYears(50))
Export-PfxCertificate -cert $cert -FilePath $PFXFilePath -Password $SecStringPw
Export-Certificate -cert $cert -FilePath $CerFilePath
X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine); store.Open(OpenFlags.ReadOnly); //var certificates = store.Certificates.Find(X509FindType.FindByThumbprint, "3de296d7b86ea9f6c2feec925134194ad54c09c6".ToUpper(), true); var certificates = store.Certificates.Find(X509FindType.FindByThumbprint, "bb417dee655caebfc85f0ab448db54becc6a495c".ToUpper(), true); var certificate = certificates[0]; services.AddIdentityServer() .AddSigningCredential(certificate) //.AddSigningCredential(new X509Certificate2(@"C:\keatkeat\self-signed-certificate\test-id4-four.pfx", "password")) //.AddValidationKey(new X509Certificate2(@"C:\keatkeat\self-signed-certificate\test-id4.pfx", "password")) //.AddDeveloperSigningCredential() .AddInMemoryApiResources(Config.GetApiResources()) .AddInMemoryClients(Config.GetClients());
run -> certmgr.msc 管理證書