Springboot整合shiro框架


shiro概述

  1. Apache Shiro是Java的一個安全框架
  2. Shiro是一個強大的簡單易用的Java安全框架,主要用來更便捷的認證、授權、加密、會話管理、與Web集成、緩存等
  3. Shiro使用起來小而簡單
  4. spring中有spring security ,是一個權限框架,它和spring依賴過於緊密,沒有shiro使用簡單。
  5. shiro不依賴於spring,shiro不僅可以實現web應用的權限管理,還可以實現c/s系統,分布式系統權限管理,
  6. shiro屬於輕量框架,越來越多企業項目開始使用shiro.

shiro核心概念

在這里插入圖片描述

  1. Authentication:身份認證/登錄,驗證用戶是不是擁有相應的身份;
  2. Authorization:授權,即權限驗證,驗證某個已認證的用戶是否擁有某個權限;
  3. Session Manager:會話管理,即用戶登錄后就是一次會話,在沒有退出之前,它的所有信息都在會話中;
  4. Cryptography:加密,保護數據的安全性
  5. Web Support:Web支持,可以非常容易的集成到Web環境;
  6. Caching:緩存,比如用戶登錄后,其用戶信息、擁有的角色/權限不必每次去查,這樣可以提高效率;
  7. Concurrency:shiro支持多線程應用的並發驗證,即如在一個線程中開啟另一個線程,能把權限自動傳播過去;
  8. Testing:提供測試支持;
  9. Run As:允許一個用戶假裝為另一個用戶(如果他們允許)的身份進行訪問;
  10. Remember Me:記住我,這個是非常常見的功能,即一次登錄后,下次再來的話不用登錄了。

主要概念

1. Subject 當前的操作用戶

  1. 可以是人 爬蟲 當前跟軟件交互的東西
  2. 在shiro當中我們可以統稱"用戶" 在代碼的任何地方,你都能輕易的獲得Shiro Subject。
  3. 一旦獲得Subject,你就可以立即獲得你希望用Shiro為當前用戶做的90%的事情 ,登錄、退、訪問會話、執行授權檢查等

2. SecurityManager

  1. SecurityManager則管理所有用戶的安全操作
  2. 引用了多個內部嵌套安全組件,是Shiro框架的核心
  3. 你可以把它看成DispatcherServlet前端控制器。
  4. 用於調度各種Shiro框架的服務

3. Realms

  1. Realms則是用戶的信息認證器和用戶的權限認證器
  2. 執行認證(登錄)和授權(訪問控制)時,Shiro會從應用配置的Realm中查找很多內容
  3. Realm 可以理解為讀取用戶信息、角色及權限的 DAO
  4. SecurityManager要驗證用戶身份與權限,那么它需要從Realm獲取相應的信息進行比較以確定用戶身份是否合法;
  5. 可以把Realm看成DataSource,即安全數據源。

4. Shiro架構

在這里插入圖片描述

  1. subject:主體 主體可以是用戶也可以是程序,主體要訪問系統,系統需要對主體進行認證、授權。
  2. authenticator: 認證器 主體進行認證最終通過authenticator進行的。
  3. authorizer: 授權器 主體進行授權最終通過authenticator進行的。
  4. sessionManager:會話管理 web應用中一般是用web容器對session進行管理,shiro也提供一套session管理的方式。
  5. sessionDao: 通過sessionDao管理session數據,
  6. cacheManager: 緩存管理器 主要對session和授權數據進行緩存,比如將授權數據通過cacheManager進行緩存管理,和 ehcache整合對緩存數據進行管理。
  7. realm: 領域 相當於數據源,通過realm存取認證、授權相關數據。
  8. cryptography: 密碼管理 提供了一套加密/解密的組件,方便開發。比如 提供常用的散列、加/解密等功能。

Springboot整合shiro

  1. 新建一個springboot項目
    在這里插入圖片描述

  2. 導入springboot-web依賴在這里插入圖片描述

  3. 編寫controller和前端登錄頁面
    需要整合thymeleaf 加入thymeleaf的依賴

 <!--thymeleaf依賴-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-java8time</artifactId>
        </dependency>

在這里插入圖片描述
4. 編寫前端頁面
在templates目錄下編寫 login.html,add.html,delete.html,index.html
導入thymeleaf的dtd

xmlns:th="http://www.thymeleaf.org"

login.html
在這里插入圖片描述

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>登錄</title>
</head>
<body>
<form th:action="login">
    <input type="text" name="username" value="">
    <input type="password" name="password" value="">
    <input type="submit" value="登錄">
</form>
</body>
</html>

index.html
在這里插入圖片描述
add.html
在這里插入圖片描述
delete.html
在這里插入圖片描述
5. 編寫controller,跳轉到登錄頁面的方法
在這里插入圖片描述

@RequestMapping({"/","tologin"})
    public String tologin(){
        return "login";
    }
  1. 運行啟動 瀏覽器輸入localhost:8080
    在這里插入圖片描述
  2. 導入springboot整合shiro和mybatis連接數據庫的依賴
    在這里插入圖片描述
		<!--shiro-整合spring的包-->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.2</version>
        </dependency>
          <!--shiro整合thymeleaf-->
        <dependency>
            <groupId>com.github.theborakompanioni</groupId>
            <artifactId>thymeleaf-extras-shiro</artifactId>
            <version>2.0.0</version>
        </dependency>
         <!--mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>
        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.38</version>
        </dependency>
  1. 創建數據庫 進行下一步的認證授權
    在這里插入圖片描述
    在這里插入圖片描述
##配置數據驅動信息  (key固定)
spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.url = jdbc:mysql:///spring_shiro
spring.datasource.username = root
spring.datasource.password =123456

在application.properties中添加數據庫信息
在這里插入圖片描述

  1. 編寫mapper,service,pojo
    pojo:
    在這里插入圖片描述
    mapper:
    在這里插入圖片描述
    service:
    在這里插入圖片描述
    Impl:
    在這里插入圖片描述
    controller:測試是否能夠查詢到
    在這里插入圖片描述
    在這里插入圖片描述
  2. 編寫shiroconfig配置類
    在這里插入圖片描述
  3. 編寫realm類 繼承AuthorizingRealm類 並實現方法
    在這里插入圖片描述
  4. 在shiroConfig中編寫代碼
    在這里插入圖片描述
@Configuration
public class shiroConfig {

    //3. shiroFilterfactaryBean
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("getDefaultWebSecurityManager") DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);//設置安全管理器
        shiroFilterFactoryBean.setLoginUrl("/toLogin");//沒有認證后跳到的頁面
        /**
         * shiro的內置過濾器
         anon:無需認證就可以訪問 默認
         authc:必須認證了才能訪問
         user:必須擁有記住我功能才能訪問
         perms:必須擁有對某個的權限才能訪問
         role:擁有某個角色權限才能訪問
         */
        //添加shiro的內置過濾器  設置要攔截的url
        Map<String,String>  filterChainDefinitionMap=new LinkedHashMap<>();//攔截
        filterChainDefinitionMap.put("/add","authc");// /add請求必須認證才能訪問
        filterChainDefinitionMap.put("/del","authc");//del必須認證才能訪問
        // filterChainDefinitionMap.put("user/**","authc");//支持通配符
        //授權
        filterChainDefinitionMap.put("/add","perms[user:add]");//沒有這個user:add權限的會被攔截下來
        filterChainDefinitionMap.put("/del","perms[user:delete]");//沒有這個user:delete權限的會被攔截下來
        //未授權的跳轉的url
        shiroFilterFactoryBean.setUnauthorizedUrl("/Unauthorized");
        //設置注銷的url
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);//把設置好的過濾設置到ShiroFilterFactoryBean
        return shiroFilterFactoryBean;
    }

    //2. DefaultWebSecurityManager
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //關聯realm對象  userRealm
        securityManager.setRealm(userRealm);
        return  securityManager;
    }
    //1. 創建realm對象 自定義的·類
    @Bean
    public UserRealm userRealm(){
        return new UserRealm();
    }

    //整合shiroDialect:用來整合shiro-thymeleaf
    @Bean
    public ShiroDialect getshiroDialect(){
        return new  ShiroDialect();
    }

}
  1. 在UserRealm編寫代碼
public class UserRealm extends AuthorizingRealm {

    @Autowired
    InfoService service;

    //授權
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("執行了授權 doGetAuthorizationInfo");
        SimpleAuthorizationInfo simpInfo = new SimpleAuthorizationInfo();
        //獲取當前用戶的對象
        Subject subject=SecurityUtils.getSubject();
        Info user = (Info)subject.getPrincipal();//獲取用戶信息
        simpInfo.addStringPermission(user.getPerm());//獲取數據庫權限
        return simpInfo;
    }

    //認證
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("執行了認證 doGetAuthorizationInfo");
        //獲取當前的用戶
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken userToken=(UsernamePasswordToken)authenticationToken;//獲取登錄的信息
        //獲取用戶名 密碼  數據庫取
        System.out.println(userToken.getUsername());
        Info query = service.queryByName(userToken.getUsername());
        System.out.println(query);
        if(query==null){//沒有這個用戶
            return null;
        }
        Session session=subject.getSession();//獲取用戶的session
        session.setAttribute("loginuser",query);

        if(!userToken.getUsername().equals(query.getUsername())){//判斷登錄的用戶名密碼 匹配數據庫是否正確
            return null;//拋出異常
        }
        //密碼認證,shiro做
        return new SimpleAuthenticationInfo(query,query.getPassword(),"");
    }
}

在這里插入圖片描述
14. 改寫controller
在這里插入圖片描述

    @RequestMapping("/login")
    public String login(String username,String password){
        try {
            //獲取當前的用戶
            Subject subject = SecurityUtils.getSubject();
            //封裝用戶的登錄數據
            UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username, password);
            subject.login(usernamePasswordToken);//執行登錄的方法 沒有異常就成功了
            return "index";
        } catch (UnknownAccountException e) {
            /**
             * 異常信息
             * UnknownAccountException :用戶名不存在
             * IncorrectCredentialsException:密碼錯誤
             */
            e.printStackTrace();
            System.out.println("用戶名不存在");
        }catch (IncorrectCredentialsException e){
            System.out.println("密碼錯誤");
        }
        return "login";
    }

    @RequestMapping("/add")
    public String add(){//跳轉頁面
        return "add";
    }
    @RequestMapping("/del")
    public String delete(){//跳轉頁面
        return "delete";
    }
     @RequestMapping("/Unauthorized")
    public String Unauthorized(){//沒有權限跳轉的url
        return "Unauthorized";
    }
    //注銷
    @RequestMapping("/logout")
    public String logout() {
        Subject subject = SecurityUtils.getSubject();
        Session session = subject.getSession();
        session.setAttribute("loginuser",null);//清空session
        return "login";
    }
  1. 編寫未授權的頁面
    Unauthorized.html
    在這里插入圖片描述
  2. 運行:
    在這里插入圖片描述

在這里插入圖片描述
root用戶只有user:delete權限 所以只能看到刪除按鈕
在這里插入圖片描述
在這里插入圖片描述
dj用戶只有user:add權限 只能看到添加
在這里插入圖片描述
在這里插入圖片描述
ss用戶什么權限也沒有 所以什么按鈕也看不見

其中還有加密方式 比如md5 可以自行添加 就不一一介紹了

重點:shiroConfig類和UserRealm類配置好 核心**


免責聲明!

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



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