shiro框架源码解析与改造(八)---PermissionsAuthorizationFilter

PermissionsAuthorizationFilter是权限验证的关键过滤器。

@Override
    protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
        return this.isAccessAllowed(request, response,mappedValue) || this.onAccessDenied(request, response,mappedValue);
    }

具体验证方法如下:
委托subject验证,subject又委托authleam数据源进行验证,

public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        Subject subject = this.getSubject(request, response);
        String[] perms = (String[])mappedValue;
        boolean isPermitted = true;
        if(perms != null && perms.length > 0) {
            if(perms.length == 1) {
                if(!subject.isPermitted(perms[0])) {
                    isPermitted = false;
                }
            } else if(!subject.isPermittedAll(perms)) {
                isPermitted = false;
            }
        }

        return isPermitted;
    }
 @Override
    public boolean isPermitted(PrincipalCollection principals, String permission) {
        this.assertRealmsConfigured();
        Iterator var3 = this.getRealms().iterator();

        Realm realm;
        do {
            if(!var3.hasNext()) {
                return false;
            }

            realm = (Realm)var3.next();
        } while(!(realm instanceof Authorizer) || !((Authorizer)realm).isPermitted(principals, permission));

        return true;
    }

这里调用AuthenAuthorityRealm的验证方法,AuthorizationInfo info = this.getAuthorizationInfo(principals);会调用用户自定义的数据源获取权限信息。

public boolean isPermitted(PrincipalCollection principals, String permission){
        Permission p = this.getPermissionResolver().resolvePermission(permission);
        AuthorizationInfo info = this.getAuthorizationInfo(principals);
        Collection<Permission> perms = this.getPermissions(info);
        if(perms != null && !perms.isEmpty()) {
            Iterator var4 = perms.iterator();

            while(var4.hasNext()) {
                Permission perm = (Permission)var4.next();
                if(perm.implies(p)) {
                    return true;
                }
            }
        }

        return false;
    }

而上面的this.onAccessDenied(request, response,mappedValue);这个方法则会在无权限的时候调用。
无权限时,则会重定向到无权限路径。

 protected boolean onAccessDenied(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {
        Subject subject = this.getSubject(request, response);
        if(subject.getPrincipal() == null) {
            this.saveRequestAndRedirectToLogin(request, response);
        } else {
            String unauthorizedUrl = this.getUnauthorizedUrl();
            HttpServletRequest httpRequest=WebUtils.toHttp(request);
            if (httpRequest.getHeader("X-Requested-With") == null || !httpRequest.getHeader("X-Requested-With").equals("XMLHttpRequest")) {
                if(StringUtils.hasText(unauthorizedUrl)) {
                    WebUtils.issueRedirect(request, response, unauthorizedUrl);
                } else {
                    WebUtils.toHttp(response).sendError(401);
                }
            }else {
                WebUtils.toHttp(response).sendError(401,"没有权限");
            }

        }

        return false;
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
shiro-redis-spring-boot-starter是一个用于集成Apache Shiro和Redis的Spring Boot Starter项目。Apache Shiro是一个强大而灵活的Java安全框架,用于身份验证、授权和会话管理等安全功能。而Redis是一个高性能的内存数据库,其具有快速的数据存取能力和持久化支持。 shiro-redis-spring-boot-starter提供了一种简化和快速集成Shiro和Redis的方式,使得在Spring Boot应用中实现安全功能变得更加容易。通过使用该Starter,我们可以方便地将Shiro的会话管理功能存储到Redis中,从而支持分布式环境下的会话共享和管理。 使用shiro-redis-spring-boot-starter可以带来以下好处: 1. 分布式环境的会话共享:通过将Shiro的会话数据存储到Redis中,不同的应用节点可以共享同一个会话,从而实现分布式环境下的会话管理和跨节点的身份验证和授权。 2. 高可用性和性能:Redis作为一个高性能的内存数据库,具有出色的数据读写能力和持久化支持,可以提供可靠的会话存储和高性能的数据访问能力。 3. 简化配置和集成:shiro-redis-spring-boot-starter提供了封装好的配置和集成方式,减少了我们自己实现集成的复杂性和工作量。 总结来说,shiro-redis-spring-boot-starter为我们提供了一种简化和快速集成Shiro和Redis的方式,使得在Spring Boot应用中实现安全功能变得更加容易和高效。通过它,我们可以实现分布式环境下的会话共享和管理,提供高可用性和性能的数据存取能力,同时简化了配置和集成的复杂性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值