SpringBoot與Shiro整合權限管理實戰


SpringBoot與Shiro整合權限管理實戰

作者 : Stanley 羅昊

轉載請注明出處和署名,謝謝!

*觀看本文章需要有一定SpringBoot整合經驗*

Shiro框架簡介

Apache Shiro是一個強大且易用的Java安全框架,執行身份驗證、授權、密碼學和會話管理。使用Shiro的易於理解的API,可以快速、輕松地獲得任何應用程序,

從最小的移動應用程序到最大的網絡和企業應用程序。

分析Shiro的核心API

其實,Shiro的核心類有三個,分別是:

1.Subject:這個類呢,我們稱之當前用戶的主體,這個用戶的主體包含了登陸、注銷等等的一些方法,還有一些判斷授權的一些方法;

2.SecurityManager:這個名稱翻譯過來就是,安全管理器的意思;

3.Realm:這個Realm呢其實我們Shiro去鏈接數據庫的一個橋梁,因為,我們的程序需要去操作數據庫去獲取一些用戶的信息,這些操作都需要Realm去完成;

這個三個API呢,都存在一些關系,比如.SecurityManager是需要去關聯我們的Realm,Subject是需要把操作交給我們的SecurityManager,總結下來就是,Subject是需要去管理我們的SecurityManager,而SecurityManager去關聯我們的Realm;

以上就是對Shiro的核心API進行的一些分析;

分析完之后,我們接下來就直接用SpringBoot與Shiro的整合,我們來看下它整合的關鍵步驟

SpringBoot整合Shiro

那么這個整合首先第一步需要導入Shiro的依賴;

【因為我用的是Gradle,所以僅展示Gradle用法】

1.修改.gradle文件,添加以下依賴

//Thymeleaf模板引擎,因為我用模板引擎所以我添加了此依賴
        compile group: 'org.thymeleaf', name: 'thymeleaf', version: '3.0.11.RELEASE'
        //Shiro
        compile group: 'org.apache.shiro', name: 'shiro-web', version: '1.4.0'
        compile group: 'org.apache.shiro', name: 'shiro-core', version: '1.4.0'
        // https://mvnrepository.com/artifact/org.apache.shiro/shiro-spring
        compile group: 'org.apache.shiro', name: 'shiro-spring', version: '1.4.0'

2.編寫Shiro的配置類

配置類需要三樣API,分別是:

 /**
     * 創建ShiroFilterFactoryBean
     * shiro過濾bean
     */

/**
     * 創建DefaultWebSecurityManager
     */

    /**
     * 創建Realm
     */

如圖:

3.自定義Realm類

因為我們需要在配置類中創建出Realm對象,所以我們需要建一個名為Realm的類:

創建后,需要繼承一個方法,這個方法是Shiro提供的:

/**
 * 自定義Realm
 */
public class UserRealm extends AuthorizingRealm {
    //執行授權邏輯
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        return null;
    }

    //執行認證邏輯
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {
      
        return null;

    }

4.在配置類中new出Realm

 

Shiro配置配置類

package com.lh.shiroStudy.shiro;


import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;


/**
 * Shiro配置類
 */
//@Configuration,聲明本類是一個配置類
@Configuration
public class ShiroConfig {

    /**
     * 創建ShiroFilterFactoryBean
     * shiro過濾bean
     */
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager securityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //設置安全管理器
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //添加Shiro過濾器
        /**
         * Shiro內置過濾器,可以實現權限相關的攔截器
         *  常用的過濾器:
         *      anon: 無需認證(登錄)可以訪問
         *      authc: 必須認證才可以訪問
         *      user: 如果使用rememberMe功能可以直接訪問
         *      perms: 該資源必須得到資源權限才可以訪問
         *      role: 該資源必須得到角色權限才可以訪問
         */

        Map<String,String>filterMap = new LinkedHashMap<String, String>();
        //左邊編寫攔截路徑
        filterMap.put("/add","authc");
        filterMap.put("/update","authc");
        filterMap.put("/testThymeleaf","authc");
        //授權過濾器
        //注意:當前授權攔截后,shiro會自動跳轉未授權頁面
        filterMap.put("/add","perms[user:add]");

        //修改跳轉的登陸頁面
        shiroFilterFactoryBean.setLoginUrl("/toLogin");

        //轉跳至未授權頁面【友好提示】
        shiroFilterFactoryBean.setUnauthorizedUrl("/aaaaaa");//懶省事所以沒有aaaa這個頁面,如果需要,請在Contoller中添加

        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
        return shiroFilterFactoryBean;
    }


    /**
     * 創建DefaultWebSecurityManager
     */
    @Bean(name = "securityManager")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("UserRealm") UserRealm userRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(userRealm);
        return securityManager;
    }



    /**
     * 創建Realm
     */
    @Bean(name = "UserRealm")
    public UserRealm getRealm(){
        return new UserRealm();
    }

}

Realm類

package com.lh.shiroStudy.shiro;

import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;


/**
 * 自定義Realm
 */
public class UserRealm extends AuthorizingRealm {
    //執行授權邏輯
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        //給資源進行授權
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        //添加資源的授權字符串
        //info.addStringPermission("user:add");

        //到數據庫查詢當前登陸用戶的授權字符串
        /**
         * <!-演示狀態-!>
         *     獲取當前用戶
         *     Subject subject = SecurityUtils.getSubject();
         *     User user = (User)subject.getPrincipal();
         *     User dbUser = userService.findById(id)
         *     info.addStringPermission(dbUser.getPerms());
         * </!-演示狀態-!>
         */
        System.out.println("執行授權邏輯");
        return null;
    }

    //執行認證邏輯
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {
        System.out.println("執行認證邏輯");
        //假設數據庫賬號與密碼是如下
        String username = "admin";
        String password = "123456";
        /**
         * 編寫Shiro判斷邏輯,比對用戶名和密碼
         */
        //1.判斷用戶名
        UsernamePasswordToken token =(UsernamePasswordToken)arg0;

        //User user = userService.findByName(token.getUsername());

        if (user == null){
            //用戶名不存在
            return null;//如果返回null,Shiro底層會拋出UnknowAccountException
        }
        //2.判斷密碼
        /**
         * 有三個參數
         * 1.需要返回給login
         * 2.是數據庫的密碼,將數據庫密碼返回,Shiro會自動判斷
         * 3.是Shiro的名字
         */
        return new SimpleAuthenticationInfo(user,password,"");

    }
}

 


免責聲明!

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



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