文章目錄
關於 ASP.NET Identity 2 時效設定
之前筆記 ASP.NET Identity 2 啟用自動鎖定機制 與 改 ASP.NET Identity 2 的 Token 時效,分別介紹到如何修改自動鎖定的結束時間以及產生 token 的預設時效,雖然兩者作用不同,但卻都有使用到一個 TimeSpan 設定,自己在這兩個設定上都遇到極為類似的問題:無法設定時效永不過期
,所以趁著假日來紀錄一下可以怎麼做
時效設定機制
為了要正確設定,首先就是了解運作機制,避免自以為是的設定反而造成 bug
自動鎖定的時效設定
預設為
TimeSpan.Zero
透過
DefaultAccountLockoutTimeSpan
來設定時效使用機制
達到設定的登入錯誤嘗試上限時,將
現在的 UTC 時間
加上DefaultAccountLockoutTimeSpan
當作鎖定結束時間
並寫入 db
Token 的時效設定
預設為
TimeSpan.FromDays(1)
透過
DataProtectorTokenProvider
的TokenLifespan
設定時效使用機制
產生 token 時僅將當下的 UTC 時間加入 hash,驗證時才加上
TokenLifespan
與驗證當下的時間進行比對
設定過期最大值
除了關閉過期檢查之外,沒有一個選項是可以直接指定永不過期的
無法直接設定
TimeSpan.MaxValue
(10675199.02:48:05.4775807)自動鎖定時就會出錯
Token 時效無法通過驗證
無法直接設定
TimeSpan.MaxValue
原因- 超出 DateTime 最大值(DateTime.MaxValue: 9999/12/31 下午 11:59:59 )
- 無論是自動鎖定還是 Token 時效,最終都會將 TimeSpan 加上一個 UTC 時間
如何設定極大值
理論值
TimeSpan.FromTicks((DateTimeOffset.MaxValue-DateTimeOffset.UtcNow).Ticks)
因為機制不同(產生 token 當下僅紀錄時間,加上 timespan 是發生在比對當下),所以這個設定雖然無法完整精準滿足
DateTimeOffset.MaxValue
(因為 TimeSpan 計算是發生在比對當下,而發 token 產生的時間點,因此不會出現 token 時間 + TimeSpan 超出 DateTime 上限的問題)實際值
理論值可以取得
DateTime.MaxValue
與DateTimeOffset.UtcNow
的精準落差,但實際上可用度很低,原因是該實際執行時會有時間差問題建議設定一個可接受的極大值即可(5000/12/31)
TimeSpan.FromTicks(new DateTime(5000,12,31).Ticks)
可以透過時間差調整設定找出最接近的極限值
TimeSpan.FromTicks((DateTime.MaxValue - DateTime.UtcNow.AddSeconds(1)).Ticks)
心得
兩種機制應該是不同人(or team) 寫的,風格不太一致,以結果來看 Token 時效的強健性(robustness)較佳:不會第一時間就噴錯誤,但也較難 debug:不會提供明顯錯誤只說 token 無效
原本對 TimeSpan 機制並不是非常有把握,經過翻查 source code 以及做了些實驗後,比較清楚整個運作原理跟設計概念,使用上應該能更得心應手
參考資訊
文章作者 Yowko Tsai
上次更新 2021-08-02
授權合約
本部落格 (Yowko's Notes) 所有的文章內容(包含圖片),任何轉載行為,必須通知並獲本部落格作者 (Yowko Tsai) 的同意始得轉載,且轉載皆須註明出處與作者。
Yowko's Notes 由 Yowko Tsai 製作,以創用CC 姓名標示-非商業性-相同方式分享 3.0 台灣 授權條款 釋出。