shiro系列定义Realm

Posted keepruning

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shiro系列定义Realm相关的知识,希望对你有一定的参考价值。

自定义realm;

/**
 * 认证和授权
 */
@Component
public class UserRealm extends AuthorizingRealm {

    @Autowired
    private UserService userService;
    @Autowired
    private AuthService authService;
    
    /**
     * 授权(验证权限时调用)
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        User user = (User)principals.getPrimaryPrincipal();
        Integer userId = user.getUserId();
        List<String> permsList = null;
        
        //系统管理员,拥有最高权限
        if(userId == 1){
            List<Auth> menuList = authService.queryList(new HashMap<String, Object>());
            permsList = new ArrayList<String>(menuList.size());
            for(Auth menu : menuList){
                permsList.add(menu.getPerms());
            }
        }else{
            permsList = userService.queryAllPerms(userId);
        }
        //用户权限列表
        Set<String> permsSet = new HashSet<String>();
        for(String perms : permsList){
            if(StringUtils.isBlank(perms)){
                continue;
            }
            permsSet.addAll(Arrays.asList(perms.trim().split(",")));
        }
        
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setStringPermissions(permsSet);
        return info;
    }

    /**
     * 认证(登录时调用)
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(
            AuthenticationToken authcToken) throws AuthenticationException {
        UsernamePasswordToken token = (UsernamePasswordToken)authcToken;
        
        //查询用户信息
        User user = userService.queryByUserName(token.getUsername());
        //账号不存在
        if(user == null) {
            throw new UnknownAccountException("账号不存在");
        }
        SimpleAuthenticationInfo info =null;
        info = new SimpleAuthenticationInfo(user, user.getPassword(), ByteSource.Util.bytes(user.getSalt()),getName());
        return info;
    }

    @Override
    public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
        HashedCredentialsMatcher shaCredentialsMatcher = new CustomUserMatche();
        shaCredentialsMatcher.setHashAlgorithmName(ShiroUtils.hashAlgorithmName);
        shaCredentialsMatcher.setHashIterations(ShiroUtils.hashIterations);
        super.setCredentialsMatcher(shaCredentialsMatcher);
    }
}

1、UserRealm父类AuthorizingRealm将获取Subject相关信息分成两步:获取身份验证信息(doGetAuthenticationInfo)及授权信息(doGetAuthorizationInfo);

2、doGetAuthenticationInfo获取身份验证相关信息:首先根据传入的用户名获取User信息;然后如果user为空,那么抛出没找到帐号异常UnknownAccountException;如果user找到但锁定了抛出锁定异常LockedAccountException;最后生成AuthenticationInfo信息,交给间接父类AuthenticatingRealm使用CredentialsMatcher进行判断密码是否匹配,如果不匹配将抛出密码错误异常IncorrectCredentialsException;另外如果密码重试此处太多将抛出超出重试次数异常ExcessiveAttemptsException;在组装SimpleAuthenticationInfo信息时,需要传入:身份信息(用户名)、凭据(密文密码)、盐(username+salt),CredentialsMatcher使用盐加密传入的明文密码和此处的密文密码进行匹配。

3、doGetAuthorizationInfo获取授权信息:PrincipalCollection是一个身份集合,因为我们现在就一个Realm,所以直接调用getPrimaryPrincipal得到之前传入的用户名即可;然后根据用户名调用UserService接口获取角色及权限信息。

以上是关于shiro系列定义Realm的主要内容,如果未能解决你的问题,请参考以下文章

shiro调用不到自定义realm

全栈编程系列SpringBoot整合Shiro(含KickoutSessionControlFilter并发在线人数控制以及不生效问题配置启动异常No SecurityManager...)(代码片段

shiro自定义realm,模拟数据库查询验证

权限框架 - shiro 自定义realm

shiro自定义realm

Shiro安全框架学习02 - 自定义Realm