采用shiro进行拦截且注解无效解决方法

shiro——>拦截

        • Shiro拦截器使用
          • 前言
          • 前置操作:
            • 相应的依赖:
            • 基本的配置
            • 创建realm类
            • 拦截的基本方式:
          • 大坑: 使用注解但是没效果 或者直接全部拦截解决方法:

Shiro拦截器使用

前言

在进行web开发的过程中我们需要对特定的资源进行拦截,只有拥有相应的权限的时候才能够进行操作、访问,在这时候我们一般会想起来 拦截器与过滤器,在这里我们使用一种框架: shiro框架内置的拦截器进行拦截,shiro是apache下的安全框架,其能够进行加密、拦截、验证登录,学习成本与spring的安全框架相比成本较低,在这里我们采用Shiro框架进行相应的拦截。

前置操作:
相应的依赖:
<dependency>
    <groupId>org.apache.shirogroupId>
    <artifactId>shiro-spring-boot-web-starterartifactId>
    <version>1.7.1version>
dependency>
基本的配置
@Configuration
public class shiroConfig {
    @Bean(name = "userRealm")
    public UserRealm userRealm() {
        System.out.println("666666666666666");
        UserRealm realm=new UserRealm();
        return realm;
    }

    @Bean("defaultWebSecurityManager")
    public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //关联realm
        securityManager.setRealm(userRealm);
        return securityManager;

    }

    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager) {

        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        factoryBean.setSecurityManager(defaultWebSecurityManager);
        //采用linkedHashmap->连续的
        Map<String,String> map=new LinkedHashMap<>();
        /*
        anon 无需验证就能够访问
        authc 必须任认证了才能够访问
        user: 必须认证且拥有记住我才能够访问
        perms 拥有某个资源权限才能够访问
        role 拥有某个角色的权限才能够访问
         */
        
        //在这里其实时进行了一系列的拦截操作,如果是大型项目可以直接/** 但是这里比较少,直接put进行添加
        map.put("/login.html","anon");
        map.put("/user/login","anon");
        //在这里进行了角色的设置,只有角色为 1 的用户才可以访问
        map.put("/user/athon","roles[1]");
        map.put("/**","authc");
        factoryBean.setFilterChainDefinitionMap(map);
        factoryBean.setLoginUrl("/login.html");
        return factoryBean;
    }


}
创建realm类
public class UserRealm extends AuthorizingRealm {
    @Resource
    UserDao userDao;
    //授权
    @Override
    //在没有进行相应的权限拦截的时候我们发现,在认证之后就不会调用这个方法 容易踩坑
    //
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //拿到作用域中的数据,在认证过程中我们将user对象放了进去,现在我们可以取出来
        System.out.println("============="+principals.getPrimaryPrincipal());
        User user = (User) principals.getPrimaryPrincipal();
        SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
        List<String> list=new LinkedList<>();
        for (int i = 0; i < user.getVIP() + 1; i++) {
            String role= String.valueOf(i);
            list.add(role);
        }
        info.addRoles(list);
        return info;
    }

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        UsernamePasswordToken token1= (UsernamePasswordToken) token;
        String username=token1.getUsername();
        User user = userDao.findUserByName(username);
        if (user == null) {
            //在这里返回null后就会报错,报错为UnknownAccountException,表示账号不存在,可以直接捕捉异常
            return null;
        }
        //密码认证在这里进行实现,如果不正确会直接报错:IncorrectCredentialsException 可以直接捕捉异常
        return new SimpleAuthenticationInfo(user,user.getPassword(),this.getName());
    }
}
拦截的基本方式:
  1. 自己手动判断:
Subject subject=SecurityUtils.getSubject();
if(subject.hasRole("1")){
    ...
}
  1. 基本的拦截方式FilterChainDefinitionMap
  2. 使用注解的方法

我们使用的根据角色进行的拦截,我们要对需要拦截的方法加上一个注解@RequiresRoles

我们需要对RequiresRoles注解进行一个认识,它是基于角色进行拦截的,我们只需要输入我们需要的角色即可,同时也可以有多个角色,这时候我们分析他的源码,可以看出来他其实是一个字符串数组的形式,因此我们可以直接写一个数组,采用shiro进行拦截且注解无效解决方法_第1张图片

用逗号隔开即可。

但是我们发现,在使用的时候会进行报错,500的报错说是不存在**的roles,这时候我们看底层的源码

采用shiro进行拦截且注解无效解决方法_第2张图片

在默认情况下,为Logical.AND,AND就很容易理解,就是必须同时满足才可以,那么如果只满足一个如何解决?我们看Logical类,发现它是一个枚举类,存在两个值:

在这里插入图片描述

or 就很容易理解,就是满足其中任意一个即可,因此我们可以直接使用Logical.or即可

大坑: 使用注解但是没效果 或者直接全部拦截解决方法:
@Bean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator(){
    DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator=new DefaultAdvisorAutoProxyCreator();
    defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
    return defaultAdvisorAutoProxyCreator;
}
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("defaultWebSecurityManager") DefaultWebSecurityManager securityManager){
    AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor=new AuthorizationAttributeSourceAdvisor();
    authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
    return authorizationAttributeSourceAdvisor;
}

将这些一并写入到配置类中即可~

带深入研究~

你可能感兴趣的:(Spring,shiro,shiro,spring)