Shiro 設計哲學:「以用戶為中心的安全模型」。本文深度解析 Shiro 核心架構圖,拆解 Subject、SecurityManager、Realm 及其內部組件 (Authenticator、Authorizer、SessionManager、CacheManager、Cryptography) 的職責與交互流程,為後續整合配置打下理論基礎。
┌─────────────────────────────────────────────────────────────┐
│ Application │
└──────────────────────────┬──────────────────────────────────┘
│ 調用 Subject API
▼
┌─────────────────────────────────────────────────────────────┐
│ Subject (當前用戶/進程/任務) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Principals │ │ Credentials │ │ Permissions│ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└──────────────────────────┬──────────────────────────────────┘
│ 委託
▼
┌─────────────────────────────────────────────────────────────┐
│ SecurityManager (核心大腦) │
│ ┌────────────┐ ┌────────────┐ ┌──────────┐ ┌────────────┐ │
│ │Authenticator│ │ Authorizer │ │SessionMgr│ │ CacheMgr │ │
│ └────────────┘ └────────────┘ └──────────┘ └────────────┘ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ Realms │ │ Cryptography│ │ EventBus │ │
│ └────────────┘ └────────────┘ └────────────┘ │
└──────────────────────────┬──────────────────────────────────┘
│ 協調
▼
┌─────────────────────────────────────────────────────────────┐
│ Realms (數據源適配器) ←→ DB / LDAP / INI / ActiveDirectory │
└─────────────────────────────────────────────────────────────┘
| 組件 | 職責 | 關鍵點 |
|---|---|---|
| Subject | 安全視圖門面,代表當前交互主體 | 綁定 SecurityManager;API 極簡 (login/logout/hasRole/isPermitted) |
| SecurityManager | 安全操作總調度器,管理所有組件生命週期 | 單例;配置完成後開發者極少直接調用 |
| Realm | 安全數據源橋梁 (DAO 模式) | 至少一個;可配置多個,按順序嘗試;實現 doGetAuthenticationInfo/doGetAuthorizationInfo |
SecurityManager
├── Authenticator (認證器)
│ ├── 支援多 Realm 串聯/並聯認證
│ └── AuthenticationStrategy (策略):
│ ├── FirstSuccessfulStrategy (默認,一成功即成功)
│ ├── AtLeastOneSuccessfulStrategy (至少一個成功)
│ └── AllSuccessfulStrategy (全部成功)
├── Authorizer (授權器)
│ ├── 基於角色/權限字符串/通配符的授權決策
│ └── 內建 WildcardPermission (資源:操作:實例)
├── SessionManager (會話管理)
│ ├── 非 Web 環境也可用的原生 Session (獨立於 Servlet)
│ ├── SessionDAO (持久化策略):Memory/EnterpriseCache/Redis/JDBC
│ └── SessionValidationScheduler (定時清理過期 Session)
├── CacheManager (緩存管理)
│ ├── 抽象緩存創建/生命週期 (Ehcache/Redis/Caffeine)
│ └── 緩存認證/授權/Session 數據,極大提升性能
├── Cryptography (加密體系)
│ ├── Hash (MD5/SHA/AES) + Salt + 多次迭代
│ ├── CipherService (對稱/非對稱加解密)
│ └── RandomNumberGenerator (安全隨機數)
└── Realms[] (多數據源協調)
├── 支援 JDBC/LDAP/ActiveDirectory/Properties/自定義
└── 配置順序決定嘗試順序
subject.login(token) → SecurityManager.authenticate(token)realm.getAuthenticationInfo(token)AuthenticationInfo (含 principals、credentials、salt)CredentialsMatcher 比對憑證 (含重試限制、加密驗證)subject.checkPermission("user:delete") → SecurityManager.authorize()realm.getAuthorizationInfo(principals)AuthorizationInfo (roles、stringPermissions、objectPermissions)Permission.implies() 匹配 → 通過/拋 AuthorizationException架構感悟:Shiro 把「安全數據從哪來」(Realm) 與「安全邏輯怎麼判」(Authenticator/Authorizer) 徹底解耦,這才是框架該有的樣子。理解了這層,配置文件就不再是無意義的 XML 堆砌,而是清晰的組件裝配圖。