溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Springboot整合Shiro中怎樣進(jìn)行權(quán)限管理

發(fā)布時(shí)間:2021-09-28 09:57:31 來(lái)源:億速云 閱讀:142 作者:柒染 欄目:大數(shù)據(jù)

這篇文章給大家介紹Springboot整合Shiro中怎樣進(jìn)行權(quán)限管理,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。

Shiro的授權(quán)流程跟認(rèn)證流程類似:

  1. 創(chuàng)建SecurityManager安全管理器

  2. Subject主體帶授權(quán)信息執(zhí)行授權(quán),請(qǐng)求到SecurityManager

  3. SecurityManager安全管理器調(diào)用Authorizer授權(quán)

  4. Authorizer結(jié)合主體一步步傳過(guò)來(lái)的授權(quán)信息與Realm中的數(shù)據(jù)比對(duì),授權(quán)

(1)我們已經(jīng)在ShiroConfig配置類中配置好了SecurityManager安全管理器

 /**
     * 配置Shiro核心 安全管理器 SecurityManager
     * SecurityManager安全管理器:所有與安全有關(guān)的操作都會(huì)與SecurityManager交互;且它管理著所有Subject;負(fù)責(zé)與后邊介紹的其他組件進(jìn)行交互。(類似于SpringMVC中的DispatcherServlet控制器)
     */
    @Bean
    public SecurityManager securityManager(){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //將自定義的realm交給SecurityManager管理
        securityManager.setRealm(new CustomRealm());
        return securityManager;
    }

(2)下面對(duì)自定義Realm類CustomRealm中的授權(quán)方法doGetAuthorizationInfo進(jìn)行重寫(xiě)

 @Override
    /**
     * 授權(quán)
     */
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {
        //獲取當(dāng)前登錄的用戶
        User user = (User) principal.getPrimaryPrincipal();
        //通過(guò)SimpleAuthenticationInfo做授權(quán)
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        //添加角色
        simpleAuthorizationInfo.addRole(user.getRole());
        //添加權(quán)限
        simpleAuthorizationInfo.addStringPermissions(user.getPermissions());
        return simpleAuthorizationInfo;
    }

上面主要通過(guò)SimpleAuthorizationInfo中的addRoleaddStringPermissions添加當(dāng)前用戶擁有的角色和權(quán)限,與主體的授權(quán)信息進(jìn)行比對(duì)。
(3)主體調(diào)用授權(quán)請(qǐng)求
主體進(jìn)行授權(quán)請(qǐng)求有兩種方式,一種是編程式,一種是注解式。
①編程式:通過(guò)SubjecthasRole()進(jìn)行角色的校檢,通過(guò)isPermitted()進(jìn)行權(quán)限的校檢

@GetMapping("/dog")
    public String dog(){
        Subject subject = SecurityUtils.getSubject();
        if(subject.hasRole("dog")){
            return "dog√";
        }
       else {
           return  "dog×";
        }
    }

    @GetMapping("/cat")
    public String cat(){
        Subject subject = SecurityUtils.getSubject();
        if(subject.hasRole("cat")){
            return "cat√";
        }
        else {
            return  "cat×";
        }
    }
 @GetMapping("/rap")
    public String rap(){
        Subject subject = SecurityUtils.getSubject();
        if(subject.isPermitted("rap")){
            return "rap";
        }else{
            return "沒(méi)權(quán)限你Rap個(gè)錘子啊!";
        }

模擬用戶數(shù)據(jù)如下:

/**
     * 模擬數(shù)據(jù)庫(kù)數(shù)據(jù)
     * @return
     */
    private List<User> getUsers(){
        List<User> users = new ArrayList<>(2);
        List<String> cat = new ArrayList<>(3);
        cat.add("sing");
        cat.add("rap");
        List<String> dog = new ArrayList<>(3);
        dog.add("jump");
        dog.add("basketball");
        users.add(new User("張小黑的貓","123qwe",true,"cat",cat));
        users.add(new User("張小黑的狗","123qwe",true,"dog",dog));
        return users;
    }

測(cè)試結(jié)果如圖:

authorization.gif

②注解式:
首先需要開(kāi)啟Aop注解,在ShiroConfig類中新增如下方法:

 /**
     * 開(kāi)啟aop注解支持
     * 即在controller中使用 @RequiresPermissions("user/userList")
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor attributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        //設(shè)置安全管理器
        attributeSourceAdvisor.setSecurityManager(securityManager);
        return attributeSourceAdvisor;
    }

    @Bean
    @ConditionalOnMissingBean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();
        defaultAAP.setProxyTargetClass(true);
        return defaultAAP;
    }

對(duì)于未授權(quán)的用戶需要進(jìn)行友好的提示,一般返回特定的403頁(yè)面,在ShiroConfig類中新增如下方法實(shí)現(xiàn):

 /**
     * 處理未授權(quán)的異常,返回自定義的錯(cuò)誤頁(yè)面(403)
     * @return
     */
    @Bean
    public SimpleMappingExceptionResolver simpleMappingExceptionResolver() {
        SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
        Properties properties = new Properties();
        /*未授權(quán)處理頁(yè)*/
        properties.setProperty("UnauthorizedException", "403.html");
        resolver.setExceptionMappings(properties);
        return resolver;
    }

解釋下上面的代碼properties.setProperty("UnauthorizedException","403.html");用來(lái)對(duì)抓取到UnauthorizedException未授權(quán)異常進(jìn)行處理,重定向到403.html頁(yè)面。我們需要?jiǎng)?chuàng)建403頁(yè)面403.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>未授權(quán)</title>
</head>
<body>
403,您沒(méi)有訪問(wèn)權(quán)限
</body>
</html>

然后在Controller使用注解@RequiresRoles("xxx")@RequiresPermissions("xxx")進(jìn)行角色和權(quán)限的校檢

    @GetMapping("/sing")
    @RequiresRoles("cat")
    public String sing(){
        return "sing";
    }
    @GetMapping("/jump")
    @RequiresPermissions("jump")
    public String jump(){
        return "jump";
    }

測(cè)試結(jié)果如圖:

authorization2.gif

總結(jié):一般對(duì)未授權(quán)用戶需要統(tǒng)一返回指定403頁(yè)面的,使用注解更加方便;需要做業(yè)務(wù)邏輯(比如對(duì)未授權(quán)的請(qǐng)求記錄進(jìn)行預(yù)警等),使用編程式更加方便。
(4)前端的shiro標(biāo)簽
通常前端頁(yè)面展示需要與用戶的權(quán)限對(duì)等,即只給用戶看到他們權(quán)限內(nèi)的內(nèi)容。(比如用戶"張小黑的貓",對(duì)應(yīng)角色“cat”,對(duì)應(yīng)權(quán)限“sing”和“rap”,那么該用戶登錄后只展示Cat、sing和rap的按鈕)
通常解決方式有兩種:
其一:登錄后通過(guò)讀取數(shù)據(jù)庫(kù)中角色和權(quán)限,獲取需要展示的菜單內(nèi)容,動(dòng)態(tài)的在前端渲染;
其二:所有內(nèi)容都在前端寫(xiě)好,通過(guò)前端的shiro標(biāo)簽控制對(duì)應(yīng)權(quán)限內(nèi)容部分的渲染。
這里給大家演示shiro標(biāo)簽的使用。(前端的shiro標(biāo)簽有Jsp標(biāo)簽、Freemarker標(biāo)簽、Thymeleaf標(biāo)簽等,演示用的為thymeleaf標(biāo)簽)

Shiro標(biāo)簽說(shuō)明:
guest標(biāo)簽:`<shiro:guest></shiro:guest>`,用戶沒(méi)有身份驗(yàn)證時(shí)顯示相應(yīng)信息,即游客訪問(wèn)信息。
user標(biāo)簽:`<shiro:user></shiro:user>`,用戶已經(jīng)身份驗(yàn)證/記住我登錄后顯示相應(yīng)的信息。
authenticated標(biāo)簽:`<shiro:authenticated></shiro:authenticated>`,用戶已經(jīng)身份驗(yàn)證通過(guò),即Subject.login登錄成功,不是記住我登錄的。
notAuthenticated標(biāo)簽:`<shiro:notAuthenticated></shiro:notAuthenticated>`,用戶已經(jīng)身份驗(yàn)證通過(guò),即沒(méi)有調(diào)用Subject.login進(jìn)行登錄,包括記住我自動(dòng)登錄的也屬于未進(jìn)行身份驗(yàn)證。
principal標(biāo)簽:`<shiro: principal/><shiro:principal property="username"/>`,相當(dāng)`((User)Subject.getPrincipals()).getUsername()`。
lacksPermission標(biāo)簽:`<shiro:lacksPermission name="org:create"></shiro:lacksPermission>`,如果當(dāng)前Subject沒(méi)有權(quán)限將顯示body體內(nèi)容。
hasRole標(biāo)簽:`<shiro:hasRole name="admin"></shiro:hasRole>`,如果當(dāng)前Subject有角色將顯示body體內(nèi)容。
hasAnyRoles標(biāo)簽:`<shiro:hasAnyRoles name="admin,user"></shiro:hasAnyRoles>`,如果當(dāng)前Subject有任意一個(gè)角色(或的關(guān)系)將顯示body體內(nèi)容。
lacksRole標(biāo)簽:`<shiro:lacksRole name="abc"></shiro:lacksRole>`,如果當(dāng)前Subject沒(méi)有角色將顯示body體內(nèi)容。
hasPermission標(biāo)簽:`<shiro:hasPermission name="user:create"></shiro:hasPermission>`,如果當(dāng)前Subject有權(quán)限將顯示body體內(nèi)容

使用:
①pom.xml引入相應(yīng)的依賴

 <!-- 兼容于thymeleaf的shiro -->
        <dependency>
            <groupId>com.github.theborakompanioni</groupId>
            <artifactId>thymeleaf-extras-shiro</artifactId>
            <version>2.0.0</version>
        </dependency>

注意:這里引用的版本是2.0.0,之前1.0.2有兼容問(wèn)題
②ShiroConfig中加入配置

 /**
     * 用于thymeleaf模板使用shiro標(biāo)簽
     * @return
     */
    @Bean
    public ShiroDialect shiroDialect() {
        return new ShiroDialect();
    }

③前端頁(yè)面使用shiro標(biāo)簽

<!--使用標(biāo)簽后 -->
<shiro:hasRole name="dog"><a href="/dog">Dog</a></shiro:hasRole>
<shiro:hasRole name="cat"><a href="/cat">Cat</a></shiro:hasRole>
<hr>
<shiro:hasPermission name="sing"><a href="/sing">Sing</a></shiro:hasPermission>
<shiro:hasPermission name="jump"><a href="/jump">Jump</a></shiro:hasPermission>
<shiro:hasPermission name="rap"><a href="/rap">Rap</a></shiro:hasPermission>
<shiro:hasPermission name="basketball"><a href="/basketball">Basketball</a></shiro:hasPermission>

注意:使用前現(xiàn)在html標(biāo)簽內(nèi)引入shiro標(biāo)簽,即<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="https://cache.yisu.com/upload/information/20210524/347/782630.gif


----------------------------------------------到這里,shiro授權(quán)基本搞定了---------------------------------------------------------
下面附上項(xiàng)目結(jié)構(gòu)和代碼:

image.png


AuthorizationController.java:

package com.cdq.shriodemo.controller;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class AuthorizationController {

    /**
     * 1.編程式:
     *  (1)通過(guò)Subject的hasRole()進(jìn)行角色的校檢
     *  (2)通過(guò)isPermitted()進(jìn)行權(quán)限的校檢
     */

    /**
     * 1.注解式:
     *  (1)使用注解@RequiresRoles("xxx")進(jìn)行角色的校檢
     *  (2)使用注解@RequiresPermissions("xxx")進(jìn)行權(quán)限的校檢
     */

    //一般對(duì)未授權(quán)用戶需要統(tǒng)一返回指定403頁(yè)面的,使用注解更加方便;
    // 需要做業(yè)務(wù)邏輯(比如對(duì)未授權(quán)的請(qǐng)求記錄進(jìn)行預(yù)警等),使用編程式更加方便。

    //編程式
    @GetMapping("/dog")
    public String dog() {
        Subject subject = SecurityUtils.getSubject();
        if (subject.hasRole("dog")) {
            return "dog√";
        } else {
            return "dog×";
        }
    }

    //編程式
    @GetMapping("/cat")
    public String cat() {
        Subject subject = SecurityUtils.getSubject();
        if (subject.hasRole("cat")) {
            return "cat√";
        } else {
            return "cat×";
        }
    }


    @GetMapping("/sing")
    @RequiresRoles("cat")//如果subject中有cat角色才可以訪問(wèn)方法sing。如果沒(méi)有這個(gè)權(quán)限則會(huì)拋出異常AuthorizationException。
    public String sing() {
        return "sing";
    }


    @GetMapping("/jump")
    @RequiresPermissions("jump")//要求subject中必須同時(shí)含有jump的權(quán)限才能執(zhí)行方法jump()。
    public String jump() {
        return "jump";
    }


    //編程式
    @GetMapping("/rap")
    public String rap() {
        Subject subject = SecurityUtils.getSubject();
        if (subject.isPermitted("rap")) {
            return "rap";
        } else {
            return "沒(méi)權(quán)限你Rap個(gè)錘子啊!";
        }

    }


    //編程式
    @GetMapping("/basketball")
    public String basketball() {
        Subject subject = SecurityUtils.getSubject();
        if (subject.isPermitted("basketball")) {
            return "basketball";
        } else {
            return "你會(huì)打個(gè)粑粑球!";
        }
    }
}

CustomRealm.java:

package com.cdq.shriodemo.shiro;

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 java.util.ArrayList;
import java.util.List;

/**
 * @Description: shiro的自定義realm
 * Realm:域,Shiro從從Realm獲取安全數(shù)據(jù)(如用戶、角色、權(quán)限),就是說(shuō)SecurityManager要驗(yàn)證用戶身份,那么它需要從Realm獲取相應(yīng)的用戶進(jìn)行比較以確定用戶身份是否合法;也需要從Realm得到用戶相應(yīng)的角色/權(quán)限進(jìn)行驗(yàn)證用戶是否能進(jìn)行操作;可以把Realm看成DataSource,即安全數(shù)據(jù)源。
 * @author ChenDeQuan
 * @data 2019-05-22 17:51
 */
public class CustomRealm extends AuthorizingRealm {
    @Override
    /**
     * 認(rèn)證
     */
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //1.獲取用戶輸入的賬號(hào)
        String username = (String)token.getPrincipal();
        //2.通過(guò)username模擬從數(shù)據(jù)庫(kù)中查找到user實(shí)體
        User user = getUserByUserName(username);
        if(user == null){
            return null;
        }
        //3.通過(guò)SimpleAuthenticationInfo做身份處理
        SimpleAuthenticationInfo simpleAuthenticationInfo =
                new SimpleAuthenticationInfo(user,user.getPassword(),getName());
        //4.用戶賬號(hào)狀態(tài)驗(yàn)證等其他業(yè)務(wù)操作
        if(!user.getAvailable()){
            throw new AuthenticationException("該賬號(hào)已經(jīng)被禁用");
        }
        //5.返回身份處理對(duì)象
        return simpleAuthenticationInfo;
    }

    @Override
    /**
     * 授權(quán)
     */
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {
        //獲取當(dāng)前登錄的用戶
        User user = (User) principal.getPrimaryPrincipal();
        //通過(guò)SimpleAuthenticationInfo做授權(quán)
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        //添加角色
        simpleAuthorizationInfo.addRole(user.getRole());
        //添加權(quán)限
        simpleAuthorizationInfo.addStringPermissions(user.getPermissions());
        return simpleAuthorizationInfo;
    }

    /**
     * 模擬通過(guò)username從數(shù)據(jù)庫(kù)中查找到user實(shí)體
     * @param username
     * @return
     */
    private User getUserByUserName(String username){
        List<User> users = getUsers();
        for(User user : users){
            if(user.getUsername().equals(username)){
                return user;
            }
        }
        return null;
    }

    /**
     * 模擬數(shù)據(jù)庫(kù)數(shù)據(jù)
     * @return
     */
    private List<User> getUsers(){
        List<User> users = new ArrayList<>(2);
        List<String> cat = new ArrayList<>(2);
        cat.add("sing");
        cat.add("rap");
        List<String> dog = new ArrayList<>(2);
        dog.add("jump");
        dog.add("basketball");
        users.add(new User("cxk1","123",true,"cat",cat));
        users.add(new User("cxk2","123",true,"dog",dog));
        return users;
    }
}

ShiroConfig.java:

package com.cdq.shriodemo.shiro;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;

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

/**
 * @Description springboot中的Shiro配置類
 * @author ChenDeQuan
 * @data 2019-05-22 17:17
 */
@Configuration
public class ShiroConfig {

    /**
     * 配置Shiro核心 安全管理器 SecurityManager
     * SecurityManager安全管理器:所有與安全有關(guān)的操作都會(huì)與SecurityManager交互;且它管理著所有Subject;負(fù)責(zé)與后邊介紹的其他組件進(jìn)行交互。(類似于SpringMVC中的DispatcherServlet控制器)
     */
    @Bean
    public SecurityManager securityManager(){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //將自定義的realm交給SecurityManager管理
        securityManager.setRealm(new CustomRealm());
        return securityManager;
    }


    /**
     * 配置Shiro的Web過(guò)濾器,攔截瀏覽器請(qǐng)求并交給SecurityManager處理
     * @return
     */
    @Bean
    public ShiroFilterFactoryBean webFilter(SecurityManager securityManager){

        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //設(shè)置securityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        //配置攔截鏈 使用LinkedHashMap,因?yàn)長(zhǎng)inkedHashMap是有序的,shiro會(huì)根據(jù)添加的順序進(jìn)行攔截
        // Map<K,V> K指的是攔截的url V值的是該url是否攔截
        Map<String,String> filterChainMap = new LinkedHashMap<String,String>(16);
        //配置退出過(guò)濾器logout,由shiro實(shí)現(xiàn)
        filterChainMap.put("/logout","logout");
        //authc:所有url都必須認(rèn)證通過(guò)才可以訪問(wèn); anon:所有url都都可以匿名訪問(wèn),先配置anon再配置authc。
        filterChainMap.put("/login","anon");
        filterChainMap.put("/**", "authc");

        //設(shè)置默認(rèn)登錄的URL.
        shiroFilterFactoryBean.setLoginUrl("/login");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainMap);
        return shiroFilterFactoryBean;
    }

    /**
     * 開(kāi)啟aop注解支持
     * 即在controller中使用 @RequiresPermissions("user/userList")
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor attributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        //設(shè)置安全管理器
        attributeSourceAdvisor.setSecurityManager(securityManager);
        return attributeSourceAdvisor;
    }

    @Bean
    @ConditionalOnMissingBean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();
        defaultAAP.setProxyTargetClass(true);
        return defaultAAP;
    }

    /**
     * 處理未授權(quán)的異常,返回自定義的錯(cuò)誤頁(yè)面(403)
     * @return
     */
    @Bean
    public SimpleMappingExceptionResolver simpleMappingExceptionResolver() {
        SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
        Properties properties = new Properties();
        /*未授權(quán)處理頁(yè)*/
        properties.setProperty("UnauthorizedException", "403.html");
        resolver.setExceptionMappings(properties);
        return resolver;
    }

    /**
     * 用于thymeleaf模板使用shiro標(biāo)簽
     * @return
     */
    @Bean
    public ShiroDialect shiroDialect() {
        return new ShiroDialect();
    }
}

User.java:

package com.cdq.shriodemo.shiro;

import java.util.List;

/**
 * @Description 用戶
 * @author ChenDeQuan
 * @data 2019-05-22 19:18
 */
public class User {
    private String username;
    private String password;
    private Boolean available;
    private String role;
    private List<String> permissions;

    public User(String username, String password, Boolean available, String role, List<String> permissions) {
        this.username = username;
        this.password = password;
        this.available = available;
        this.role = role;
        this.permissions = permissions;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Boolean getAvailable() {
        return available;
    }

    public void setAvailable(Boolean available) {
        this.available = available;
    }

    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }

    public List<String> getPermissions() {
        return permissions;
    }

    public void setPermissions(List<String> permissions) {
        this.permissions = permissions;
    }
}

success.html:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
    <meta charset="UTF-8">
    <title>success</title>
</head>
<body>
<span th:text="'歡迎你,'+${username}"></span>
<br>
<!--使用標(biāo)簽前 -->
<!--<a href="/dog">Dog</a>-->
<!--<a href="/cat">Cat</a>-->
<!--<hr>-->
<!--<a href="/sing">Sing</a>-->
<!--<a href="/jump">Jump</a>-->
<!--<a href="/rap">Rap</a>-->
<!--<a href="/basketball">Basketball</a>-->
<!--<hr>-->

<!--使用標(biāo)簽后 -->
<shiro:hasRole name="dog"><a href="/dog">Dog</a></shiro:hasRole>
<shiro:hasRole name="cat"><a href="/cat">Cat</a></shiro:hasRole>
<hr>
<shiro:hasPermission name="sing"><a href="/sing">Sing</a></shiro:hasPermission>
<shiro:hasPermission name="jump"><a href="/jump">Jump</a></shiro:hasPermission>
<shiro:hasPermission name="rap"><a href="/rap">Rap</a></shiro:hasPermission>
<shiro:hasPermission name="basketball"><a href="/basketball">Basketball</a></shiro:hasPermission>

</body>
</html>

關(guān)于Springboot整合Shiro中怎樣進(jìn)行權(quán)限管理就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI