分布式使用shiro作权限2

第一步 
新建UserRealm 

1.做登陆认证(执行一次)
把登陆后该用户的权限信息,存到session中
2.做权限控制授权
把session中的信息拿出来
User user = (User) principals.getPrimaryPrincipal();
然后授权(执行多次)
simpleAuthorizationInfo.addRoles(roles);
simpleAuthorizationInfo.addStringPermissions(permissions);
-----------弊端--------懒加载权限配置后需要重新登陆,且登陆时间长


第二种方法
1.UserRealm 做登陆认证
只做登陆认证,不查询权限信息,权限信息不放入session
2.(有session的id,就可以查询所以登陆了)加载菜单,同时把权限(菜单地址)信息放入redis中
3.UserRealm 做授权,把redis的权限信息取出来授权(执行多次)
4.修改权限时,redis被改,因为授权执行多次,使用权限注解,都会执行,所以无需重新登陆





第一种

@Configuration
public class UserRealm extends AuthorizingRealm{

    /**
     * 授权 执行n次
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        User user = (User) principals.getPrimaryPrincipal();
        List<String> roles = user.getRoles();//取出权限信息
        List<String> permissions = user.getPermissions();
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.addRoles(roles);
        simpleAuthorizationInfo.addStringPermissions(permissions);
        return simpleAuthorizationInfo;
    }

    /**
     * 登录 执行一次
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String username = token.getPrincipal().toString();
        // 使用用户名查询用户
        // 查询该用户的权限信息
        // 返回AuthenticationInfo 对象
        User user = new User();
        user.setUsername(username);
        user.setPassword("b53b8594f4e0ec33b5f3ed8c29c2a81b");
        user.setRoles(Arrays.asList("admin"));//模拟权限信息
        user.setPermissions(Arrays.asList("admin:add"));//模拟权限信息
        ByteSource salt = ByteSource.Util.bytes("whsxt".getBytes());
        return new SimpleAuthenticationInfo(user, user.getPassword(), salt,username);//存
    }

}

第二种-------------------------------------------------------
@Configuration
public class UserRealm extends AuthorizingRealm{

    @Autowired
    private SysUserService userService;

    @Autowired
    private StringRedisTemplate redis;
    /**
     * 
     * 授权 执行n次
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SysUser user = (SysUser)principals.getPrimaryPrincipal();
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        String authJson = redis.opsForValue().get(Auth.USER_AUTH_PREFIX+user.getUserId());//redis中取权限信息
        JSONArray jsonArray =JSONUtil.parseArray(authJson);
        // 只要简单的权限
        List<String> permissions = JSONUtil.toList(jsonArray, String.class);
        simpleAuthorizationInfo.addStringPermissions(permissions);
        return simpleAuthorizationInfo;
    }

    /**
     * 登录 执行一次
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String username = token.getPrincipal().toString();
        // 使用用户名查询用户
        SysUser sysUser = userService.findUserByUsername(username);
        if(sysUser==null) { // 若用户不存在,应该return null ,而不是把null 也放在SimpleAuthenticationInfo 里面
            return null ;
        }
        // 查询该用户的权限信息 ,但是若是权限或菜单查询失败,则用户就登录失败 了
        // 返回AuthenticationInfo 对象
        return new SimpleAuthenticationInfo(sysUser, sysUser.getPassword(), ByteSource.Util.bytes("whsxt".getBytes()),username);
    }


}

 

posted @ 2020-11-18 16:25  java_静止  阅读(603)  评论(0编辑  收藏  举报