Springboot集成Shiro--自定义权限过滤器

在使用Shiro进行权限判断的时候,某一个访问路径,可能只需要两种权限中的其中一个,就可以访问。但是Shiro中,提供的权限过滤,必须都满足两个权限之后,才能访问,这样会造成一些权限控制的不合理人性化。因此自定义权限过滤器是非常有必要的,在日后的开发中,自定义权限过滤器是很频繁的操作。

1.Shiro中的权限控制

#需要同时拥有order:add和order:query权限才可以访问
/order-add = perms["order:add","order:query"]
#只需要order:del权限就可以访问
/order-del = perms["order:del"]

perms表示的就是权限控制,中括号中就是需要访问等号之前路径,需要的权限名称。如果在使用Shiro过滤器的时候,不配置过滤器,就会使用默认的过滤器。

以下是默认权限过滤器的源码。

public class PermissionsAuthorizationFilter extends AuthorizationFilter {
    public PermissionsAuthorizationFilter() {
    }

    public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {
        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;
    }
}

从上面的代码可以看出,我们的配置会默认被强转为string类型的字符串数组。当只有一个权限时,会直接判断有没有该权限; 当配置多个权限时,从下面的代码可以看出只用在请求url的用户拥有所有的权限时,才会返回true,否则就会被拒绝访问。

2.Shiro框架的权限过滤局限了日常的开发

shiro源码只实现了权限同时拥有或者单个拥有才能访问指定路径的问题,并没有实现用户拥有多个权限中的其中一个权限就可以访问指定路径的问题。

因此为了满足业务需求,在自定义拦截器中需要重写PermissionsAuthorizationFilter的isAccessAllowed方法。

自定义权限过滤器 PermissionOrFilter

public class PermissionOrFilter extends AuthorizationFilter {


    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
        Subject subject = this.getSubject(request, response);
        String[] perms = (String[]) ((String[]) mappedValue);
        boolean isPermitted = true;
        if (perms != null && perms.length > 0) {
            if (perms.length == 1) {
                if (!isOneOfPermitted(perms[0], subject)) {
                    isPermitted = false;
                }
            } else if (!isAllPermitted(perms,subject)) {
                isPermitted = false;
            }
        }
        return isPermitted;
    }

    /**
     * 以“,”分割的权限为并列关系的权限控制,分别对每个权限字符串进行“|”分割解析
     * 若并列关系的权限有一个不满足则返回false
     *
     * @param permStrArray 以","分割的权限集合
     * @param subject      当前用户的登录信息
     * @return 是否拥有该权限
     */
    private boolean isAllPermitted(String[] permStrArray, Subject subject) {
        boolean isPermitted = true;
        for (int index = 0, len = permStrArray.length; index < len; index++) {
            if (!isOneOfPermitted(permStrArray[index], subject)) {
                isPermitted = false;
            }
        }
        return isPermitted;
    }

    /**
     * 判断以“|”分割的权限有一个满足的就返回true,表示权限的或者关系
     *
     * @param permStr 权限数组种中的一个字符串
     * @param subject 当前用户信息
     * @return 是否有权限
     */
    private boolean isOneOfPermitted(String permStr, Subject subject) {
        boolean isPermitted = false;
        String[] permArr = permStr.split("\\|");
        if (permArr.length > 0) {
            for (int index = 0, len = permArr.length; index < len; index++) {
                if (subject.isPermitted(permArr[index])) {
                    isPermitted = true;
                }
            }
        }
        return isPermitted;
    }
}

在ShiroConfig中配置自定义的权限过滤器

	/**
     * @Description 加载自定义过滤器
     */
    private Map<String, Filter> filters(){
        Map<String,Filter> map = new HashMap<>();
        //map的键,表示在配置权限控制的时候中括号前的属性值
        	//例如:/order-add = permissions-or["order:add","order:query"]
        map.put("permissions-or", new PermissionOrFilter());
        return map;
    }


//shiro过滤器管理
    @Bean("shiroFilter")
    public ShiroFilterFactoryBean shiroFilterFactoryBean(){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //设置该配置类中的安全管理器
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager());
        //设置自定义的过滤器
        shiroFilterFactoryBean.setFilters(filters());
		Map<String,String> map = new HashMap();
		....
		权限配置省略
		.....
        //过滤器链
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        shiroFilterFactoryBean.setLoginUrl("/login");
        shiroFilterFactoryBean.setUnauthorizedUrl("/login");
        return shiroFilterFactoryBean;
    }

这样的配置,可以在权限过滤器配置的时候,使用逗号 , 表示并列拥有才可以访问,使用 | 表示多个权限拥有其中一个权限就可以访问。

修改后的演示

//表示同时拥有这两个权限才可以访问
/order-add = perms["order:add","order:query"]
//表示拥有这两个权限其中一个就可以访问
/order-add = perms["order:add"|"order:query"]
  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Spring Boot是基于Spring框架的快速开发应用程序的工具,而Shiro则是一个强大且灵活的Java安全框架。将Spring BootShiro结合使用可以实现权限管理的功能。 首先需要在Spring Boot项目中引入相关依赖,包括Spring Boot的依赖和Shiro的依赖。可以在pom.xml文件中添加如下依赖: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.7.1</version> </dependency> ``` 接下来,需要配置Shiro的配置类。可以创建一个继承自org.apache.shiro.web.mgt.DefaultWebSecurityManager的类,并在该类中配置Shiro的相关信息,包括认证器和授权器。 认证器负责验证用户的身份,可以使用Shiro提供的Realm来实现自定义的身份验证逻辑。授权器负责判断用户是否有权限执行某个操作,可以使用Shiro提供的Permission类来实现权限的控制。 然后,需要为Spring Boot应用程序配置Shiro过滤器链。可以使用Shiro的FilterChainDefinitionMap类来配置URL与权限的映射关系。可以在一个继承自org.apache.shiro.web.env.AbstractWebEnvironment的类中配置这些过滤器链。 最后,在Spring Boot应用程序的入口类中启动Shiro配置。在main()方法中,可以使用org.apache.shiro.SecurityUtils类的setSecurityManager()方法来设置Shiro的安全管理器。 完成以上步骤后,Spring Boot应用程序就集成Shiro权限管理功能。可以通过编写相应的Controller和页面来测试权限管理的效果。 总之,通过将Spring BootShiro结合使用,可以实现权限管理的功能。通过配置Shiro的相关类和过滤器链,以及编写自定义的Realm和Permission,可以实现身份验证和权限控制的逻辑。 ### 回答2: Spring Boot是一个用于创建独立的、基于Spring的应用程序的框架。Shiro是一个强大的Java安全框架,提供了身份认证、授权、加密等安全功能。下面是使用Spring Boot集成Shiro权限管理的步骤和注意事项。 1. 添加依赖:在Maven或Gradle中添加Spring BootShiro的依赖项。 2. 创建Shiro配置类:创建一个继承自`org.apache.shiro.spring.config.ShiroAnnotationProcessorConfiguration`的配置类。在该类中配置Shiro的安全相关属性,比如加密算法、身份认证方式等。 3. 创建用户实体类:创建表示用户的实体类,并为其添加相关属性,如用户名、密码等。 4. 创建用户服务类:创建一个用户服务类,用于处理用户相关的操作,如用户注册、查询用户等。 5. 创建Realm类:创建一个继承自`org.apache.shiro.realm.AuthorizingRealm`的自定义Realm类。在该类中,实现身份认证和授权的逻辑。 6. 配置Shiro过滤器:在`application.properties`文件中配置Shiro过滤器链,指定URL与权限之间的对应关系。 7. 创建Controller类:创建一个Controller类,用于处理用户请求。在该类中,通过`@RequiresRoles`和`@RequiresPermissions`等注解为方法添加授权需求。 8. 启动应用程序:使用Spring Boot的注解启动应用程序,让Spring Boot自动配置并启用Shiro。 注意事项: - 在配置Shiro时,需要根据实际需要选择适当的安全策略、加密算法和认证方式。 - 在自定义Realm类中,需要根据实际需求进行身份认证和授权的实现。 - 在通过Shiro注解为方法添加授权需求时,需要确保用户已经成功登录。 - 需要根据实际业务需求,合理配置Shiro过滤器链,以获得所需的权限控制效果。 总之,使用Spring Boot集成Shiro权限管理可以方便地实现应用程序的安全认证和授权功能。通过配置Shiro的相关属性和自定义Realm类,可以实现灵活的权限管理,保护应用程序的安全。 ### 回答3: Spring Boot集成Shiro权限管理是一种常用的方式,可以实现安全的身份验证和授权功能。以下是一个简单的步骤,来演示如何实现这个集成。 第一步,导入相关依赖。在pom.xml文件中添加以下依赖项: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring-boot-web-starter</artifactId> <version>1.7.1</version> </dependency> ``` 第二步,编写Shiro的配置文件。创建一个类,命名为ShiroConfig,并使用@Configuration注解将其声明为一个配置类。在配置类中,使用@RequiresPermissions注解来定义URL的访问权限,使用@Bean注解来创建ShiroFilterFactoryBean和DefaultWebSecurityManager等Bean。 第三步,创建一个自定义的Realm类。这个类需要继承自AuthenticatingRealm,并实现其中的认证和授权方法。在认证方法中,需要根据用户名和密码来进行验证用户的身份。在授权方法中,需要判断用户是否具有访问某个URL的权限。 第四步,在Spring Boot的启动类中,添加@EnableCaching注解来启用缓存功能。这样可以提高系统的性能。 第五步,编写Controller类。在Controller中,使用@RequiresPermissions注解来定义URL的访问权限。在方法中,可以使用Subject进行身份验证和授权操作。 最后,启动应用程序。通过访问配置的URL,可以验证是否成功实现了Shiro权限管理功能。 通过以上步骤,我们可以实现Spring Boot集成Shiro权限管理。这样就可以在应用程序中实现安全的身份验证和授权功能,确保只有具备相应权限的用户可以访问指定的URL。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值