Shiro笔记七:自定义Shiro Filter过滤器

Shiro笔记七:自定义Shiro Filter过滤器

shiro自带的Filter的问题
  1. shiro有自带的过滤器在DefaultFilter里面,但是有个问题。

filterChainDefinitionMap.put("/admin/**",“roles[admin,root]”);//中括号里面的是角色的名字

这里面的问题是:只有当用户属于admin和root角色时,才能访问这个路径,如果只有root角色或者只有admin角色,是不能访问的。相当于hasAllRole()

  1. 现在的需求是:只需要有其中一个角色就能满足访问。这就需要自定义Filter

自定义Filter,继承AuthorizationFilter,重写里面的isAccessAllowed方法。

public class CustomRolesOrAuthorizationFilter extends AuthorizationFilter {

    public CustomRolesOrAuthorizationFilter(){

    }

    @Override
    public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {
        Subject subject = this.getSubject(request, response);
        //获取当前访问路径所需要的角色集合
        String[] rolesArray = (String[])((String[])mappedValue);
        if (rolesArray != null && rolesArray.length != 0) {
            Set<String> roles = CollectionUtils.asSet(rolesArray);
            //当前subject是roles中的任意一个,则有权访问。
            for(String role:roles){
                if(subject.hasRole(role)){
                    return true;
                }
            }
            return false;
        } else {
            return true;
        }
    }
}
  1. 修改调用的过滤器链
filterChainDefinitionMap.put("/admin/**","roleOrFilter[admin,root]");//中括号里面的是角色的名字。
使用Redis整合CacheManager
  1. 使用redis原因

授权的时候每次都去查询数据库,对于频繁访问接口,性能和响应速度比较慢,使用缓存代替之。

  1. 解决方案:

一是:在业务代码查询数据库的时候,添加进程缓存。

二是:使用Redis缓存。

  1. 使用Redis缓存步骤:

1、添加依赖,shiro+redis的缓存插件

<!-- shiro+redis缓存插件 -->
<dependency>
    <groupId>org.crazycake</groupId>
    <artifactId>shiro-redis</artifactId>
    <version>3.1.0</version>
</dependency>
  1. 编写redis配置类
/**
     * 配置RedisManager
     * @return
     */
public RedisManager getRedisManager(){

    RedisManager redisManager=new RedisManager();
    redisManager.setHost("localhost");
    redisManager.setPort(6379);
    redisManager.setDatabase(1);
    return redisManager;

}
  1. 将Redis配置整合到Shiro的CacheManager
/**
     * 配置CacheManager的具体实现类
     * @return
     */
public RedisCacheManager cacheManager(){//RedisCacheManager实现了CacheManager的接口
    RedisCacheManager redisCacheManager=new RedisCacheManager();
    redisCacheManager.setRedisManager(getRedisManager());
    //设置过期时间20s
    redisCacheManager.setExpire(20);
    return redisCacheManager;

}

4、让整合redis的cacheManager作为shiro的缓存方案。在SecurityManager里面配置

@Bean
public SecurityManager securityManager(){
    DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
    securityManager.setSessionManager(sessionManager());
    //使用自定义的cacheManager
    securityManager.setCacheManager(cacheManager());//此处添加缓存配置。
    //推荐放到最后,不然某些版本不生效
    securityManager.setRealm(customRealm());

    return securityManager;
}
使用Redis整合SessionManager
  1. 为什么要对Session持久化

重启应用,用户无感知,可以继续以原先的状态继续访问。

  1. 持久化

1、使用Redis持久化,结合Shiro的RedisSessionDAO进行持久化

2、使用RedisSessionDAO加载Redis组件。

3、使用SessionManager加载RedisSessionDao。

4、注意实体类要进行序列化

/**
     * 自定义redis持久化
     * @return
     */
public RedisSessionDAO redisSessionDAO(){
    RedisSessionDAO redisSessionDAO=new RedisSessionDAO();
    redisSessionDAO.setRedisManager(getRedisManager());
    redisSessionDAO.setExpire(20);
    return redisSessionDAO;
}

SessionManager加载RedisSessionDao

/**
     * 设置会话,自定义Session
     * @return
     */
@Bean
public SessionManager sessionManager(){
    CustomSessionManager customSessionManager=new CustomSessionManager();
    //设置会话超时时间,单位是毫秒,默认是30分钟
    //customSessionManager.setGlobalSessionTimeout(200000);
    //配置session持久化
    customSessionManager.setSessionDAO(redisSessionDAO());
    return customSessionManager;
}
ShiroConfig中常用Bean类配置
  1. LifecycleBeanPostProcessor

作用:管理shiro一些bean的生命周期 即bean初始化 与销毁,注意管理的只是Shiro的Bean.

/**
     * 作用:管理shiro一些bean的生命周期 即bean初始化 与销毁
     * @return
     */
@Bean
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
    return new LifecycleBeanPostProcessor();
}
  1. AuthorizationAttributeSourceAdvisor

作用:加入注解的使用,不加入这个AOP注解不生效(shiro的注解 例如 @RequiresGuest)

/**
     * 作用:加入注解的使用,不加入这个AOP注解不生效(shiro的注解 例如 @RequiresGuest)
     * @return
     */
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
    AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
    authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
    return authorizationAttributeSourceAdvisor;
}

  1. DefaultAdvisorAutoProxyCreator

作用: 用来扫描上下文寻找所有的Advistor(通知器), 将符合条件的Advisor应用到切入点的Bean中,需
要在LifecycleBeanPostProcessor创建后才可以创建

/**
     * 作用: 用来扫描上下文寻找所有的Advistor(通知器), 将符合条件的Advisor应用到切入点的Bean中,需
     * 要在LifecycleBeanPostProcessor创建后才可以创建
     * @return
     */
@Bean
@DependsOn("lifecycleBeanPostProcessor")
public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
    DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
    defaultAdvisorAutoProxyCreator.setUsePrefix(true);
    return defaultAdvisorAutoProxyCreator;
}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值