SpringBoot+Shiro权限管理

一. 添加依赖

首先,在项目的pom.xml文件中添加Spring Boot和Shiro的相关依赖:

java 复制代码
<dependencies>
    <!-- Spring Boot Starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Shiro Spring Boot Starter -->
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-spring</artifactId>
        <version>1.8.0</version>
    </dependency>

    <!-- 其他可能需要的依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
</dependencies>

二. 配置Shiro

创建一个配置类来初始化Shiro,并配置安全规则。

java 复制代码
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

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

@Configuration
public class ShiroConfig {

    @Bean
    public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        // 设置安全管理器
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        // 拦截器.
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        // 配置不会被拦截的链接
        filterChainDefinitionMap.put("/login", "anon");
        filterChainDefinitionMap.put("/css/**", "anon");
        filterChainDefinitionMap.put("/js/**", "anon");
        filterChainDefinitionMap.put("/**", "authc");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        // 设置realm
        securityManager.setRealm(myShiroRealm());
        return securityManager;
    }

    @Bean
    public MyShiroRealm myShiroRealm() {
        MyShiroRealm realm = new MyShiroRealm();
        return realm;
    }

    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

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

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }
}

三. 创建Realm

Realm是Shiro与数据源交互的桥梁,用于进行身份验证和授权。

java 复制代码
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

public class MyShiroRealm extends AuthorizingRealm {

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        // 获取登录用户名
        String username = (String) principals.getPrimaryPrincipal();
        // 查询用户的角色和权限
        // 这里通常需要从数据库获取,这里为了演示,直接返回固定值
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.addRole("admin");
        authorizationInfo.addStringPermission("user:query");
        return authorizationInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        // 获取用户名和密码
        String username = (String) token.getPrincipal();
        String password = new String((char[]) token.getCredentials());

        if (!"admin".equals(username)) {
            throw new UnknownAccountException(); // 如果用户名错误
        }
        if (!"123".equals(password)) {
            throw new IncorrectCredentialsException(); // 如果密码错误
        }

        // 如果没有抛出异常则表示登陆成功,返回一个AuthenticationInfo实现
        return new SimpleAuthenticationInfo(username, password, getName());
    }
}

四. 控制器示例

最后,我们可以创建一个控制器来测试权限控制。

java 复制代码
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {

    @GetMapping("/hello")
    @RequiresRoles("admin")
    @RequiresPermissions("user:query")
    public String hello() {
        return "Hello, you have the permission to view this page.";
    }
}
相关推荐
天若有情673几秒前
Deepseek-V4-Flash-20260423 深度评测与实战指南
java·大数据·网络·ai
折哥的程序人生 · 物流技术专研6 分钟前
《Java 100 天进阶之路》第32篇:Java常用工具类(Objects、Collections、Arrays深入)
java·后端·面试·求职招聘
憧憬成为java架构高手的小白7 分钟前
苍穹外卖项目-day02
java·spring
一只大袋鼠10 分钟前
SpringBoot 入门学习笔记(三)Web 开发下篇
spring boot·笔记·学习
西凉的悲伤16 分钟前
SpringBoot RestTemplate 介绍
java·spring boot·后端·resttemplate
Roselind_Yi1 小时前
池化对比:CNN池化 VS Java线程池
java·人工智能·经验分享·笔记·深度学习·神经网络·cnn
IT_Octopus9 小时前
Spring Boot 实战:@PostConstruct + Caffeine 缓存初始化与定时刷新
spring boot·后端·缓存
Java面试题总结10 小时前
java高频面试题(2026最新)
java·开发语言·jvm·数据库·spring·缓存
苦逼的猿宝10 小时前
学生心理咨询评估系统
java·毕业设计·springboot·计算机毕业设计
隔窗听雨眠10 小时前
doctype、charset、meta如何控制整个渲染流水线
java·服务器·前端