Realm:
在实际应用中,shiro从数据库中获取安全数据(如用户、角色、权限),而不是从ini中,可作为安全数据源
即SecurityManager要验证用户身份,那么它需要从Realm获取相应的用户进行比较以确定用户身份是否合法
也需要从Realm中得到用户相应的角色/权限以确定用户是否能进行操作
org.apache.shiro.realm.Realm:
String getName(); //返回一个唯一的Realm名字 boolean supports(AuthenticationToken token); //判断此Realm是否支持此Token AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException; //根据Token获取认证信息
1 自定义Realm:
一般实现AuthorizingRealm(授权)接口即可,此接口继承了AuthenticatingRealm(身份验证),也简介集成了CachingRealm(缓存)接口
ini配置指定自定义Realm
[main] #自定义realm customRealm=com.roxy.shiro.realm.CustomRealm #指定secrityManager的Realm实现 securityManager.realm=$customRealm
realm:
public class CustomRealm extends AuthenticatingRealm{ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { // 从数据库获取用户名和密码 String username = "draco"; String password = "615"; //从用户的输入中生成token,拿到用户名密码 String inputUsername = (String)token.getPrincipal(); if(!inputUsername.equals(username)){ throw new UnknownAccountException("用户不存在"); } /* if(status == 0){ throw new LockedAccountException("用户被锁定"); }*/ String inputPassword = (String)token.getCredentials(); if(!inputPassword.equals(password)){ throw new IncorrectCredentialsException("密码不正确"); } System.out.println(this.getName()); String realName = this.getName();
//拿到授权信息 SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(inputUsername, inputPassword, realName); return info; } }
测试出现错误:
错误信息提示类型转换错误,猜测username或者password的类型转换出错,但是日志已经将username打印出来,所以password转换出错
2017-10-14 20:24:34,680 WARN [org.apache.shiro.authc.AbstractAuthenticator] -
Authentication failed for token submission [org.apache.shiro.authc.UsernamePasswordToken - draco, rememberMe=false].
Possible unexpected error? (Typical or expected login exceptions should extend from AuthenticationException). java.lang.ClassCastException: [C cannot be cast to java.lang.String
将代码改为:
String inputPassword = new String((char[])token.getCredentials());
再次测试:
2017-10-14 20:28:41,793 DEBUG [com.roxy.shiro.quickstart.Quickstart] - 密码错误 2017-10-14 20:28:41,794 DEBUG [com.roxy.shiro.quickstart.Quickstart] - 是否登陆成功:false
2 多Realm配置:
[main] #自定义realm customRealm=com.roxy.shiro.realm.CustomRealm
customRealm2=com.roxy.shiro.realm.CustomRealm2
#指定secrityManager的Realm实现 (可选,若不指定,按照声明的顺序进行使用)
securityManager.realm=$customRealm,$customRealm2
SecurityManager会按照Realms指定的顺序进行身份验证
如果Realm没有被显示的指定,则会被忽略