2023-05-14 Shiro整合springboot

一妇拯、流程圖

ShiroFilter會(huì)攔截用戶發(fā)來(lái)的所有請(qǐng)求针史,然后判斷該請(qǐng)求是否需要做認(rèn)證和授權(quán)羊异,也就是判斷該請(qǐng)求訪問(wèn)的是受限資源還是公共資源,訪問(wèn)受限資源的話就要做認(rèn)證和授權(quán),利用SecurityManager铲咨、Realm做認(rèn)證嘲更、授權(quán)闸溃,認(rèn)證失敗跳轉(zhuǎn)到登錄頁(yè)勋陪,訪問(wèn)公共資源的話直接放行


image

二贪磺、shiro中的過(guò)濾器

image

三、整合步驟

1.引入shiro依賴(lài)

<dependency>

    <groupId>org.apache.shiro</groupId>

    <artifactId>shiro-spring-boot-starter</artifactId>

    <version>1.5.3</version>

</dependency>

2.創(chuàng)建自定義Realm類(lèi)

這里面完成認(rèn)證和授權(quán)相關(guān)業(yè)務(wù)

package com.szhedu.springboot_shiro.shiro.realms;

import com.szhedu.springboot_shiro.mapper.UserMapper;
import com.szhedu.springboot_shiro.pojo.User;
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.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Objects;

/**
 * 自定義的realm
 */
public class CustomerRealm extends AuthorizingRealm {
    @Autowired
    private UserMapper userMapper;
    //授權(quán)
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String primaryPrincipal = (String) principalCollection.getPrimaryPrincipal();
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.addRole("admin");
        authorizationInfo.addStringPermission("user:add:*");
        return authorizationInfo;
    }

    //認(rèn)證
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String principal = (String) authenticationToken.getPrincipal();
        //查詢數(shù)據(jù)庫(kù)诅愚,如果用戶名和密碼都校驗(yàn)成功寒锚,則認(rèn)證通過(guò)
        User user = userMapper.getUser(principal);
        if(!Objects.isNull(user)){
            SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
                    principal,
                    user.getPassword(),
                    //鹽
                    ByteSource.Util.bytes(user.getSalt()),
                    this.getName());
            return authenticationInfo;
        }
        return null;
    }
}

3.編寫(xiě)shiro配置類(lèi),包含三步①創(chuàng)建ShiroFilter②創(chuàng)建全局安全管理器③創(chuàng)建自定義Realm

package com.szhedu.springboot_shiro.config;

import com.szhedu.springboot_shiro.shiro.realms.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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * shiro配置類(lèi)
 */
@Configuration
public class ShiroConfig {
    //1.創(chuàng)建ShiroFilter
    @Bean
    public ShiroFilterFactoryBean getShiroFilter(DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
        //todo 1. 將全局安全管理器注入
        shiroFilter.setSecurityManager(defaultWebSecurityManager);
        //todo 2.設(shè)置受限資源
        Map<String, String> map = new HashMap<>();
        //公共資源先放開(kāi)
        map.put("/user/login","anon");
        map.put("/user/register","anon");
        map.put("/register.jsp","anon");
        //authc表示這個(gè)資源需要認(rèn)證和授權(quán)违孝,如果沒(méi)認(rèn)證成功默認(rèn)回到login.jsp
        map.put("/**","authc");
        shiroFilter.setFilterChainDefinitionMap(map);
        return shiroFilter;
    }
    //2.創(chuàng)建全局安全管理器
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManager(Realm realm){
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
        //將自定義的realm設(shè)置到全局安全管理器中
        defaultWebSecurityManager.setRealm(realm);
        return defaultWebSecurityManager;
    }
    //3.創(chuàng)建自定義Realm
    @Bean
    public Realm getRealm(){
        CustomerRealm customerRealm = new CustomerRealm();
        //todo 修改憑證校驗(yàn)匹配器
        //這里刹前,就會(huì)先對(duì)用戶輸入的密碼進(jìn)行MD5加密,然后再用加密后的密碼去和數(shù)據(jù)庫(kù)中的密碼做equals判斷
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        //使用的算法
        hashedCredentialsMatcher.setHashAlgorithmName("md5");
        //散列的次數(shù)
        hashedCredentialsMatcher.setHashIterations(1024);
        customerRealm.setCredentialsMatcher(hashedCredentialsMatcher);
        return customerRealm;
    }
}

4.登錄接口(認(rèn)證)

  //登錄
    @PostMapping("/user/login")
    public String login(String username,String password){
        Subject subject = SecurityUtils.getSubject();
        try {
            //會(huì)調(diào)用我們自定義的realm類(lèi)進(jìn)行認(rèn)證和授權(quán)
            subject.login(new UsernamePasswordToken(username,password));
            return "redirect:/index.jsp";
        } catch (UnknownAccountException e) {
            e.printStackTrace();
            System.out.println("用戶名錯(cuò)誤");
        }catch (IncorrectCredentialsException e){
            e.printStackTrace();
            System.out.println("密碼錯(cuò)誤");
        }
        return "redirect:/login.jsp";
    }

5.授權(quán):從數(shù)據(jù)庫(kù)查詢登陸用戶的角色信息和所具有的權(quán)限信息雌桑,封裝到SimpleAuthorizationInfo對(duì)象中返回

 //授權(quán)
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String primaryPrincipal = (String) principalCollection.getPrimaryPrincipal();
        List<Role> roles = userMapper.getRoles(primaryPrincipal);
        if (roles != null){
            SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
            roles.stream().forEach(
                    role -> {
                        //封裝角色信息
                        authorizationInfo.addRole(role.getName());
                        //封裝權(quán)限信息
                        List<Perms> perms = userMapper.getPerms(role.getId());
                        perms.forEach(
                                perm -> {
                                    authorizationInfo.addStringPermission(perm.getName());
                                }
                        );
                    }
            );
            return authorizationInfo;
        }
        return null;
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末喇喉,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子校坑,更是在濱河造成了極大的恐慌拣技,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,252評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件撒踪,死亡現(xiàn)場(chǎng)離奇詭異过咬,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)制妄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)掸绞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人耕捞,你說(shuō)我怎么就攤上這事衔掸。” “怎么了俺抽?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,814評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵敞映,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我磷斧,道長(zhǎng)振愿,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,869評(píng)論 1 299
  • 正文 為了忘掉前任弛饭,我火速辦了婚禮冕末,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘侣颂。我一直安慰自己档桃,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,888評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布憔晒。 她就那樣靜靜地躺著藻肄,像睡著了一般蔑舞。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上嘹屯,一...
    開(kāi)封第一講書(shū)人閱讀 52,475評(píng)論 1 312
  • 那天攻询,我揣著相機(jī)與錄音,去河邊找鬼抚垄。 笑死蜕窿,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的呆馁。 我是一名探鬼主播桐经,決...
    沈念sama閱讀 41,010評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼浙滤!你這毒婦竟也來(lái)了阴挣?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,924評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤纺腊,失蹤者是張志新(化名)和其女友劉穎畔咧,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體揖膜,經(jīng)...
    沈念sama閱讀 46,469評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡誓沸,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,552評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了壹粟。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拜隧。...
    茶點(diǎn)故事閱讀 40,680評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖趁仙,靈堂內(nèi)的尸體忽然破棺而出洪添,到底是詐尸還是另有隱情,我是刑警寧澤雀费,帶...
    沈念sama閱讀 36,362評(píng)論 5 351
  • 正文 年R本政府宣布干奢,位于F島的核電站,受9級(jí)特大地震影響盏袄,放射性物質(zhì)發(fā)生泄漏忿峻。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,037評(píng)論 3 335
  • 文/蒙蒙 一辕羽、第九天 我趴在偏房一處隱蔽的房頂上張望逛尚。 院中可真熱鬧,春花似錦逛漫、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,519評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)克握。三九已至,卻和暖如春枷踏,著一層夾襖步出監(jiān)牢的瞬間菩暗,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,621評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工旭蠕, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留停团,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,099評(píng)論 3 378
  • 正文 我出身青樓掏熬,卻偏偏與公主長(zhǎng)得像佑稠,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子旗芬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,691評(píng)論 2 361