自定义Realm简介
一般情况现自定义Realm是继承AuthorizingRealm。
Realm的继承关系:AuthorizingRealm->AuthenticatingRealm->CachingRealm->Realm。
步骤
- 创建一个类 ,继承AuthorizingRealm。
- 重写授权方法 doGetAuthorizationInfo。
- 重写认证方法 doGetAuthenticationInfo。
重写方法介绍
- 当用户登陆的时候会调用 doGetAuthenticationInfo。
- 进行权限校验的时候会调用: doGetAuthorizationInfo。
实体对象介绍
- UsernamePasswordToken:对应就是 shiro的token中有Principal和Credential,继承关系UsernamePasswordToken-》HostAuthenticationToken-》AuthenticationToken
- SimpleAuthorizationInfo:代表用户角色权限信息
- SimpleAuthenticationInfo:代表该用户的认证信息
代码实战
自定义CustomRealm
/** * @ClassName: CustomRealm * 自定义Realm * @Description: * @Author: Coding_wxb * @Date 2019.08.02 2:24 */ public class CustomRealm extends AuthorizingRealm { /** *模拟用户 **/ private final Map<String,String> userInfoMap = new HashMap<>(); { userInfoMap.put("woxbwo","123"); userInfoMap.put("zbbiex","456"); } /** *模拟role -> permission **/ private final Map<String, Set<String>> permissionMap = new HashMap<>(); { Set<String> set1 = new HashSet<>(); Set<String> set2 = new HashSet<>(); set1.add("video:find"); set1.add("video:buy"); set2.add("video:add"); set2.add("video:delete"); permissionMap.put("woxbwo",set1); permissionMap.put("zbbiex",set2); } /** *模拟user -> role **/ private final Map<String,Set<String>> roleMap = new HashMap<>();{ Set<String> set1 = new HashSet<>(); Set<String> set2 = new HashSet<>(); set1.add("role1"); set1.add("role2"); set2.add("root"); roleMap.put("woxbwo",set1); roleMap.put("zbbiex",set2); } /** *@description: * 该方法会在权限校验是调用 *@params: [principals] *@return: org.apache.shiro.authz.AuthorizationInfo **/ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { System.out.println("权限 doGetAuthorizationInfo"); String name = (String)principals.getPrimaryPrincipal(); Set<String> permissions = getPermissionsByNameFromDB(name); Set<String> roles = getRolesByNameFromDB(name); SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(); simpleAuthorizationInfo.setRoles(roles); simpleAuthorizationInfo.setStringPermissions(permissions); return simpleAuthorizationInfo; } /** *@description: * 该方法会在用户身份认证时调用 *@params: [token] *@return: org.apache.shiro.authc.AuthenticationInfo **/ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { System.out.println("认证 doGetAuthenticationInfo"); //从token获取身份信息,token代表用户输入的信息 String name = (String)token.getPrincipal(); //模拟从数据库中取密码 String pwd = getPwdByUserNameFromDB(name); if(StringUtils.isEmpty(pwd)){ return null; } SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(name, pwd, this.getName()); return simpleAuthenticationInfo; } /** * 模拟从数据库获取用户角色集合 * @param name * @return */ private Set<String> getRolesByNameFromDB(String name) { return roleMap.get(name); } /** * 模拟从数据库获取权限集合 * @param name * @return */ private Set<String> getPermissionsByNameFromDB(String name) { return permissionMap.get(name); } /** * 模拟从数据库获取密码 * @param name * @return */ private String getPwdByUserNameFromDB(String name) { return userInfoMap.get(name); } }
创建测试类
/** * @ClassName: CustomRealmTest * @Description: * @Author: Coding_wxb * @Date 2019.08.02 2:50 */ public class CustomRealmTest { private CustomRealm customRealm = new CustomRealm(); private DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager(); @Before public void init(){ //构建环境 defaultSecurityManager.setRealm(customRealm); SecurityUtils.setSecurityManager(defaultSecurityManager); } @Test public void testAuthentication() { //获取当前操作的主体 Subject subject = SecurityUtils.getSubject(); //用户输入的账号密码 UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken("woxbwo", "123"); subject.login(usernamePasswordToken); //登录 System.out.println("认证结果:"+subject.isAuthenticated()); //拿到主体标示属性 System.out.println("getPrincipal=" + subject.getPrincipal()); subject.checkRole("role1"); System.out.println("是否有对应的角色:"+subject.hasRole("role1")); System.out.println("是否有对应的权限:"+subject.isPermitted("video:add")); } }
测试结果
认证 doGetAuthenticationInfo 认证结果:true getPrincipal=woxbwo 权限 doGetAuthorizationInfo 权限 doGetAuthorizationInfo 是否有对应的角色:true 权限 doGetAuthorizationInfo 是否有对应的权限:false