真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

SpringBoot怎么整合Shiro實(shí)現(xiàn)權(quán)限控制

這篇文章主要介紹“SpringBoot怎么整合Shiro實(shí)現(xiàn)權(quán)限控制”,在日常操作中,相信很多人在SpringBoot怎么整合Shiro實(shí)現(xiàn)權(quán)限控制問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”SpringBoot怎么整合Shiro實(shí)現(xiàn)權(quán)限控制”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

創(chuàng)新互聯(lián)建站長期為1000+客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊從業(yè)經(jīng)驗10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為鳳城企業(yè)提供專業(yè)的成都網(wǎng)站建設(shè)、做網(wǎng)站鳳城網(wǎng)站改版等技術(shù)服務(wù)。擁有10余年豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。

1、SpringBoot整合Shiro

Apache Shiro是一個強(qiáng)大且易用的Java安全框架,執(zhí)行身份驗證、授權(quán)、密碼和會話管理。

1.1、shiro簡介

shiro有個核心組件,分別為Subject、SecurityManager和Realms

  • Subject:相當(dāng)于當(dāng)前操作的”用戶“,這個用戶不一定是一個具體的人,是一個抽象的概念,表明的是和當(dāng)前程序進(jìn)行交互的任何東西,例如爬蟲、腳本、等等。所有的Subject都綁定到SecurityManager上,與 Subject 的所有交互都會委托給 SecurityManager;可以把 Subject 認(rèn)為是一個門面;SecurityManager 才是實(shí)際的執(zhí)行者。

  • SecurityManager:這個是shiro框架的核心,所有與安全相關(guān)的操作都會與它進(jìn)行交互,它管理者所有的Subject。

  • Realms:充當(dāng)了Shiro與應(yīng)用安全數(shù)據(jù)間的”橋梁“,當(dāng)對用戶執(zhí)行認(rèn)證(登錄)和授權(quán)(訪問控制)驗證時,SecurityManager 需要從 Realm 獲取相應(yīng)的用戶進(jìn)行比較以確定用戶身份是否合法;也需要從 Realm 得到用戶相應(yīng)的角色 / 權(quán)限進(jìn)行驗證用戶是否能進(jìn)行操作。

1.2、代碼的具體實(shí)現(xiàn)

1.2.1、Maven的配置

 
 
            org.apache.shiro
            shiro-spring-boot-starter
            1.7.1
        
         
         
            com.github.theborakompanioni
            thymeleaf-extras-shiro
            2.0.0
        
 
  
            org.apache.shiro
            shiro-ehcache
            1.7.1
        

shiro默認(rèn)是與jsp進(jìn)行使用的,而這里是shiro整合thymeleaf所有要導(dǎo)入shiro整合thymeleaf的jar包

1.2.2、整合需要實(shí)現(xiàn)的類

  • 一般來說整合只需要完成兩個類的實(shí)現(xiàn)即可

  • 一個是 ShiroConfig 一個是 CustomerRealm

  • 如果需要添加shiro緩存并且不是自帶的緩存而是redis緩存還需要進(jìn)行另外兩個類的編寫

  • 一個是 RedisCache 一個是 RedisCacheManager

1.2.3、項目結(jié)構(gòu)

SpringBoot怎么整合Shiro實(shí)現(xiàn)權(quán)限控制

1.2.4、ShiroConfig的實(shí)現(xiàn)

未加shiro的緩存

package com.yuwen.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import com.yuwen.shiro.cache.RedisCacheManager;
import com.yuwen.shiro.realm.CustomerRealm;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.realm.Realm;
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.HashMap;
import java.util.Map;
@Configuration
public class ShiroConfig {

    //讓頁面shiro標(biāo)簽生效
    @Bean
    public ShiroDialect shiroDialect(){
        return new ShiroDialect();
    }

    //1、創(chuàng)建shiroFilter   負(fù)責(zé)攔截所有請求
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        //給filter設(shè)置安全管理
        factoryBean.setSecurityManager(defaultWebSecurityManager);
        //配置系統(tǒng)的受限資源
        //配置系統(tǒng)公共資源 全部都能訪問的設(shè)置anon
        Map map = new HashMap<>();
        map.put("/main","authc");//請求這個資源需要認(rèn)證和授權(quán) authc表示需要認(rèn)證后才能訪問
        map.put("/admin","roles[admin]"); //表示admin角色才能訪問 roles[]表示需要什么角色才能訪問
        map.put("/manage","perms[user:*:*]"); //表示需要user:*:*權(quán)限才能訪問 perms[]表示需要什么權(quán)限才能訪問
        //訪問需要認(rèn)證的頁面如果未登錄會跳轉(zhuǎn)到/login路由進(jìn)行登陸
        factoryBean.setLoginUrl("/login");
        //訪問未授權(quán)頁面會自動跳轉(zhuǎn)到/unAuth路由
        factoryBean.setUnauthorizedUrl("/unAuth");
        factoryBean.setFilterChainDefinitionMap(map);
        return factoryBean;
    }
    //2、創(chuàng)建安全管理器
    @Bean
    public DefaultWebSecurityManager defaultWebSecurityManager(@Qualifier("getRealm") Realm realm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //給安全管理器設(shè)置
        securityManager.setRealm(realm);
        return securityManager;
    }
    //3、創(chuàng)建自定義的realm
    @Bean
    public Realm getRealm(){
        CustomerRealm customerRealm = new CustomerRealm();
        //修改憑證校驗匹配器
        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
        //設(shè)置加密算法為md5
        credentialsMatcher.setHashAlgorithmName("MD5");
        //設(shè)置散列次數(shù)
        credentialsMatcher.setHashIterations(1024);
        customerRealm.setCredentialsMatcher(credentialsMatcher);
        return customerRealm;
    }
}

因為一般在數(shù)據(jù)庫中設(shè)置明文密碼不安全,所有我這里對密碼進(jìn)行了md5加密,我的加密方式為:密碼 = 密碼+鹽+散列次數(shù) 而后進(jìn)行MD5加密 所以這里創(chuàng)建自定義的realm時需要進(jìn)行設(shè)置匹配器這樣登錄時密碼才能匹配成功

1.2.5、CustomerRealm的實(shí)現(xiàn)

package com.yuwen.shiro.realm;

import com.yuwen.pojo.User;
import com.yuwen.pojo.vo.ViewPerms;
import com.yuwen.pojo.vo.ViewRole;
import com.yuwen.service.UserService;
import com.yuwen.shiro.salt.MyByteSource;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import javax.annotation.Resource;
import java.util.List;

//自定義realm
public class CustomerRealm extends AuthorizingRealm {

    @Resource
    private UserService userService;
 //授權(quán)
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        //獲取身份信息
        String primaryPrincipal = (String)principalCollection.getPrimaryPrincipal();
        //根據(jù)主身份信息獲取角色 和 權(quán)限信息
        List roles = userService.findRolesByUsername(primaryPrincipal);
        if (!CollectionUtils.isEmpty(roles)){
            SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
            roles.forEach(viewRole -> {
                simpleAuthorizationInfo.addRole(viewRole.getName());
                //權(quán)限信息
                List perms = userService.findPermsByRoleId(viewRole.getName());
                if (!CollectionUtils.isEmpty(perms)){
                    perms.forEach(viewPerms -> {
                        simpleAuthorizationInfo.addStringPermission(viewPerms.getPName());
                    });
                }
            });
            return simpleAuthorizationInfo;
        }
        return null;
    }
    
 //認(rèn)證
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //獲取登入的身份信息
        String principal = (String) authenticationToken.getPrincipal();
        User user = userService.findByUsername(principal);
        if (!ObjectUtils.isEmpty(user)){
            //ByteSource.Util.bytes(user.getSalt()) 通過這個工具將鹽傳入
            //如果身份認(rèn)證驗證成功,返回一個AuthenticationInfo實(shí)現(xiàn);
            return new SimpleAuthenticationInfo(user.getUsername(),user.getPassword(),new MyByteSource(user.getSalt()),this.getName());
        }
        return null;
    }
}

在登錄時會自動調(diào)用這個身份驗證 在驗證時如果出錯,會報異常,我在controller層接收了異常并處理

controller層中登錄時的異常處理

@PostMapping("/login")
    public String login(String username,String password){
        //獲取主體對象
        Subject subject = SecurityUtils.getSubject();
        try {
         //自動調(diào)用CustomerRealm 類中的身份驗證方法
            subject.login(new UsernamePasswordToken(username,password));
            return "index";
        }catch (UnknownAccountException e){ //接收異常并處理
            e.printStackTrace();
            model.addAttribute("msg","用戶名有誤,請重新登錄");
        }catch (IncorrectCredentialsException e){//接收異常并處理
            e.printStackTrace();
            model.addAttribute("msg","密碼有誤,請重新登錄");
        }
        return "login";
    }

1.2.6、shiro緩存配置

定義了shiro緩存,用戶登錄后,其用戶信息、擁有的角色 / 權(quán)限不必每次去查,這樣可以提高效率

默認(rèn)緩存的配置

在 ShiroConfig中 的 getRealm() 方法中開啟緩存管理

 @Bean
    public Realm getRealm(){
        CustomerRealm customerRealm = new CustomerRealm();
        //開啟緩存管理
        customerRealm.setCacheManager(new EhCacheManager());
        //開啟全局緩存
        customerRealm.setCachingEnabled(true);
        //開啟認(rèn)證緩存
        customerRealm.setAuthenticationCachingEnabled(true);
        customerRealm.setAuthenticationCacheName("authenticationCache");
        //開啟權(quán)限緩存
        customerRealm.setAuthorizationCachingEnabled(true);
        customerRealm.setAuthorizationCacheName("authorizationCache");
        return customerRealm;
    }

與reids整合的緩存這里就不說明了,放在源碼里自己查看,源碼在下方

1.2.7、主頁index.html的設(shè)置

在這里用標(biāo)簽來判斷某些區(qū)域需要認(rèn)證或什么角色或者什么權(quán)限才能訪問




    
    首頁
    


index

退出
    main | manage | admin
用戶:

    顯示認(rèn)證通過內(nèi)容
    沒有認(rèn)證時 顯示
    admin角色 顯示
    具有用戶模塊的"user:*:*"權(quán)限 顯示

1.3、簡單測試

SpringBoot怎么整合Shiro實(shí)現(xiàn)權(quán)限控制

1.3.1、admin角色所有權(quán)限測試

SpringBoot怎么整合Shiro實(shí)現(xiàn)權(quán)限控制

1.3.2、無角色有權(quán)限測試

SpringBoot怎么整合Shiro實(shí)現(xiàn)權(quán)限控制

1.3.3、無角色無權(quán)限測試

SpringBoot怎么整合Shiro實(shí)現(xiàn)權(quán)限控制
SpringBoot怎么整合Shiro實(shí)現(xiàn)權(quán)限控制

到此,關(guān)于“SpringBoot怎么整合Shiro實(shí)現(xiàn)權(quán)限控制”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!


本文題目:SpringBoot怎么整合Shiro實(shí)現(xiàn)權(quán)限控制
網(wǎng)站地址:http://weahome.cn/article/ipippc.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部