SpringBoot + Shiro + shiro.ini 的踩坑記錄



0、寫在前面的話

好久沒寫博客了,誒,好多時候偷懶直接就抓網上的資料丟筆記里了,也就沒有自己提煉,偷懶偷懶。然后最近參加了一個網絡課程,要交作業的那種,為了能方便看下其他同學的作業,就寫了個爬蟲把作業爬下來,進而想到如果以后還有類似這種情況,我需要一個非常輕量化的架子,但是權限依然是必須要用到的,否則寫個接口人人都可以調用那還得了,但是我僅僅需要一個人或者一兩個人的權限配置就可以了,所以像之前我寫過一個基於RBAC的架子甚至都還是有點嫌重(而且那個架子還沒有前端頁面,哈,真是懶),所以想到了用shiro.ini。

Shiro在很多quick start的demo中都用到了shiro.ini配置文件,用來配置賬戶密碼、角色、權限,它也寫好了現成的方法可以讀取文件直接給你配置好SecurityManager,所以省去了自己在代碼里定義Realm、配置過濾器啥的,但是實際上大家在做Web時基本都不用這玩意兒,因為自定義其實也不是很費時,我也就是蛋疼吧,既然都鼓搗了,那就還是鼓搗到有個雛形。

1、踩坑記錄

Shiro好久沒碰了,又重新回顧了下大概幾個概念:
  • SecurityManager是核心,所有和安全有關的操作都要和它交互,而且管理者所有Subject
  • Realm用來驗證用戶,可以理解為DataSource安全數據源
  • 權限攔截是通過過濾器,配置好urls和shiro默認過濾器的映射關系,shiro將會對requestUrl進行過濾鏈的匹配,並選擇過濾器進行處理

[users]
zhang=123,admin
wang=123,admin,vip

[roles]
admin=user:delete


[urls]
/static/**=anon
/login=anon
/authc/admin/user/delete=perms["user:delete"]
/authc/admin/user/create=perms["user:create"]
/authc/admin/**=roles[admin]
/authc/home=roles[admin,vip]
/authc/**=authc
shiro.ini中的 [main] 用不上了,因為這部分的配置和SpringBoot結合就在類中進行配置,這里就不需要了,只需要 [users]、[roles]、[urls],其中[users] 和 [roles] 用來創建 Realm,[urls] 用來配置過濾器

踩坑:
  • urls過濾匹配中,是按順序執行匹配到的第一個過濾器,所以要注意順序,如上圖如果把 /authc/** 放在開頭,后面的基本就匹配不到了
  • urls中對於諸如perms或roles的描述,是“且”不是“或”
    • 比如 roles[admin,vip] 表示同時擁有admin和vip角色的賬戶,而不是擁有admin或vip角色的賬戶
  • * 匹配零個或多個字符    ** 匹配零個或多個路徑

@Configuration
public class ShiroConfig {

    @Bean
    public DefaultWebSecurityManager securityManager() {
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
        SecurityManager securityManager = factory.getInstance();

        DefaultSecurityManager defaultSecurityManager = (DefaultSecurityManager) securityManager;
        DefaultWebSecurityManager webSecurityManager = new DefaultWebSecurityManager();
        webSecurityManager.setRealms(defaultSecurityManager.getRealms()); //important

        SecurityUtils.setSecurityManager(securityManager);
        return webSecurityManager;
    }

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

        Ini ini = new Ini();
        ini.loadFromPath("classpath:shiro.ini");
        Map<String, String> map = new LinkedHashMap<>();

        ini.getSection("urls").entrySet().forEach(url -> {
            map.put(url.getKey(), url.getValue());
        });
        //過濾鏈
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);

        shiroFilterFactoryBean.setLoginUrl("/login");
        shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");
        return shiroFilterFactoryBean;
    }

}

踩坑
  • SecurityManager是一定要有的,但是Shiro中讀取shiro返回的是 DefaultSecurityManager,因為是Web應用我們需要的是 DefaultWebSecurityManager,所以把 DefaultSecurityManager的Realms 提出來給 DefaultWebSecurityManager
  • 過濾鏈還是得注入在Bean中的 FilterChainDefinitionMap 屬性才是,所以對於shiro.ini的配置,使用 Ini 類的 loadFromPath 來讀取,再放置到map中

...
<packaging>war</packaging>
...

...
<!-- jsp支持 start -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <scope>provided</scope>
</dependency>

<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<!-- jsp支持 end -->
...
#application.properties
spring.mvc.view.prefix=/WEB-INF/pages/
spring.mvc.view.suffix=.jsp

SpringBoot 對 JSP 的支持並不友好,所以需要一些額外的配置,參考資料《 Spring Boot 添加 JSP 支持


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM