Realm:域,Shiro 從從Realm獲取安全數據(如用戶、角色、權限),就是說SecurityManager要驗證用戶身份,那么它需要從Realm獲取相應的用戶進行比較以確定用戶身份是否合法;
也需要從Realm得到用戶相應的角色/權限進行驗證用戶是否能進行操作;可以把Realm看成DataSource , 即安全數據源。
Realm接口如下
String getName(); //返回一個唯一的Realm名字 boolean supports(AuthenticationToken token); //判斷此Realm是否支持此Token AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException; //根據Token獲取認證信息
單Realm配置
1.自定義Realm實現
package me.shijunjie.realms; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.IncorrectCredentialsException; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authc.UnknownAccountException; import org.apache.shiro.authc.UsernamePasswordToken; import org.apache.shiro.realm.Realm; public class MyRealm1 implements Realm { public String getName() { return "MyRealm1"; } public boolean supports(AuthenticationToken token) { // 僅支持UsernamePasswordToken 類型的Token return token instanceof UsernamePasswordToken; } public AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { String userName = (String) token.getPrincipal(); String password = new String((char[])token.getCredentials()); //得到密碼 if (!"zhang".equals(userName)) { throw new UnknownAccountException(); // 如果用戶名錯誤 } if (!"123".equals(password)) { throw new IncorrectCredentialsException(); // 如果密碼錯誤 } // 如果身份認證驗證成功,返回一個AuthenticationInfo實現; return new SimpleAuthenticationInfo(userName, password, getName()); } }
2、ini配置文件指定自定義Realm實現(shiro-realm.ini)
#聲明一個realm myRealm1=me.shijunjie.realms.MyRealm1 #指定securityManager的realms實現 securityManager.realms=$myRealm1
3.測試示例
@Test public void testRealm() { // 1、獲取SecurityManager工廠,此處使用Ini配置文件初始化SecurityManager Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-realm.ini"); //2、得到SecurityManager實例並綁定給SecurityUtils SecurityManager securityManager = factory.getInstance(); SecurityUtils.setSecurityManager(securityManager); //3、得到Subject及創建用戶名/密碼身份驗證Token(即用戶身份/憑證) Subject subject = SecurityUtils.getSubject(); UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123"); try { //4、登錄,即身份驗證 subject.login(token); } catch (AuthenticationException e) { //5、身份驗證失敗 System.out.println("身份驗證失敗"); } //斷言用戶已經登錄 Assert.assertEquals(true, subject.isAuthenticated()); subject.logout(); }
多 Realm配置
1、ini配置文件(shiro-multi-realm.ini)
#聲明一個realm myRealm1=com.github.zhangkaitao.shiro.chapter2.realm.MyRealm1 myRealm2=com.github.zhangkaitao.shiro.chapter2.realm.MyRealm2 #指定securityManager的realms實現 securityManager.realms=$myRealm1,$myRealm2
1、ini配置文件(shiro-multi-realm.ini)
securityManager會按照realms指定的順序進行身份認證。此處我們使用顯示指定順序的方
式指定了Realm的順序,如果刪除“securityManager.realms=$myRealm1,$myRealm2”,那
么securityManager會按照realm聲明的順序進行使用(即無需設置realms屬性,其會自動
發現),當我們顯示指定realm 后, 其他沒有指定realm 將被忽略,如
“securityManager.realms=$myRealm1”,那么myRealm2 不會被自動設置進去