【三】shiro入门 之 Realm
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 不会被自动设置进去