spring-boot整合shiro,doGetAuthorizationInfo不调用问题

作者: 白云飞 分类: java 发布时间: 2019-12-30 21:58 阅读:

这两天想用spring-boot写一个rbac的后台通用框架,准备采用shiro。查看了各种,关于 spring-boot如何整合shiro的方法。自己也尝试着搭建了一下。虽然整体没什么问题,可以正常登录,但是,就是发现 鉴权的 doGetAuthorizationInfo根本没有调动,权限不起作用。检查一下代码如下:

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("权限配置-->MyShiroRealm.doGetAuthorizationInfo()");
        String username = (String) SecurityUtils.getSubject().getPrincipal();
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();

        authorizationInfo.addRole("2");
        authorizationInfo.addStringPermission("group/index");
        return authorizationInfo;
    }

这里我模拟登陆的用户有 role: 2 和 group/index 的权限。可是此时,我登录 /seller/list 依旧可以登录,这就纳闷了。经过一番查找,发现,应该是自己去在代用的controller上通过注解确定需要什么权限才可以,于是乎改造 controller,加上权限的校验 @RequiresPermissions(“seller/list”)

@Controller
@RequestMapping("/seller")
public class SellerController {

    @Autowired
    private SellerService sellerService;

    @RequestMapping("/list")
    @RequiresPermissions("seller/list")
    public ModelAndView sellerList() {

        List<SellerEntity> list = sellerService.getSellerList();

        ModelAndView mv = new ModelAndView();
        mv.setViewName("/seller/list");
        mv.addObject("list", list);

        return mv;
    }
}

从代码上看,访问 /seller/list 需要 seller/list 权限才可以,启动测试,依旧是没启动任何作用,doGetAuthorizationInfo 依旧是未被调用。又经过一番查找,发现,原来maven 需要 引入aop

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

另外,shiroconfig 也需要配置关于 aop的配置,下面放出我的 ShiroConfig,希望帮助到同样问题的人。

@Configuration
public class ShiroConfig {

    @Bean(name = "shiroFilter")
    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        // <!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
        filterChainDefinitionMap.put("/static/**", "anon");
        filterChainDefinitionMap.put("/login", "anon");

        // 主要这行代码必须放在所有权限设置的最后,不然会导致所有 url 都被拦截 剩余的都需要认证
        filterChainDefinitionMap.put("/**", "authc");

        // 自动跳去登录的地址
        shiroFilterFactoryBean.setLoginUrl("/login");
        // 未授权页面
        shiroFilterFactoryBean.setUnauthorizedUrl("/403");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager defaultSecurityManager = new DefaultWebSecurityManager();
        defaultSecurityManager.setRealm(customRealm());
        // 注入session的管理
        defaultSecurityManager.setSessionManager(sessionManager());
        return defaultSecurityManager;
    }

    @Bean
    public SellerRealm customRealm() {
        SellerRealm sellerRealm = new SellerRealm();
        return sellerRealm;
    }

    /**
     * 管理session
     * @return
     */
    @Bean
    public DefaultWebSessionManager sessionManager() {
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        // 去掉shiro登录时url里的JSESSIONID
        sessionManager.setSessionIdUrlRewritingEnabled(false);
        return sessionManager;
    }

    /**
     * 开启注解
     * @param securityManager
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);

        return authorizationAttributeSourceAdvisor;
    }
}

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!