GitHub_Trending/sp/spring-reading安全框架:Shiro与Spring集成

GitHub_Trending/sp/spring-reading安全框架:Shiro与Spring集成

【免费下载链接】spring-reading 涵盖了 Spring 框架的核心概念和关键功能,包括控制反转(IOC)容器的使用,面向切面编程(AOP)的原理与实践,事务管理的方式与实现,Spring MVC 的流程与控制器工作机制,以及 Spring 中数据访问、安全、Boot 自动配置等方面的深入研究。此外,它还包含了 Spring 事件机制的应用、高级主题如缓存抽象和响应式编程,以及对 Spring 源码的编程风格与设计模式的深入探讨。 【免费下载链接】spring-reading 项目地址: https://gitcode.com/GitHub_Trending/sp/spring-reading

1. 安全框架选型痛点与解决方案

你是否正面临Spring应用权限管理的以下困境:

  • 手写拦截器实现认证逻辑导致代码冗余
  • 权限控制散落在业务代码中难以维护
  • 缺乏统一的会话管理和加密策略

Apache Shiro(四郎)作为轻量级安全框架,提供认证(Authentication)授权(Authorization)会话管理(Session Management)加密(Cryptography) 四大核心功能,与Spring框架的无缝集成可完美解决上述问题。本文将从环境配置、核心组件、实战案例到性能优化,系统化讲解Shiro与Spring的集成方案。

2. 环境准备与依赖配置

2.1 必要依赖坐标

<!-- Shiro核心依赖 -->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-core</artifactId>
    <version>1.12.0</version>
</dependency>
<!-- Spring集成模块 -->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.12.0</version>
</dependency>
<!-- 缓存支持 -->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-ehcache</artifactId>
    <version>1.12.0</version>
</dependency>

2.2 项目结构规范

src/main/java
├── com/example/security
│   ├── config/          # Shiro配置类
│   │   ├── ShiroConfig.java
│   │   └── CustomRealm.java
│   ├── controller/      # 受保护资源
│   └── service/         # 业务逻辑层
src/main/resources
├── shiro.ini            # 传统配置方式(可选)
└── spring-shiro.xml     # Spring整合配置

3. 核心组件与工作原理

3.1 Shiro架构流程图

mermaid

3.2 核心组件说明

组件名称作用常见实现类
Subject代表当前用户org.apache.shiro.subject.Subject
SecurityManager安全核心管理器org.apache.shiro.web.mgt.DefaultWebSecurityManager
Realm数据源连接器org.apache.shiro.realm.AuthorizingRealm
FilterChainURL拦截过滤器org.apache.shiro.web.filter.mgt.DefaultFilterChainManager
SessionDAO会话持久化org.apache.shiro.session.mgt.eis.MemorySessionDAO

4. 详细集成步骤

4.1 自定义Realm实现

public class CustomRealm extends AuthorizingRealm {
    @Autowired
    private UserService userService;
    
    // 授权逻辑
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        String username = (String) principals.getPrimaryPrincipal();
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        // 查询用户角色
        Set<String> roles = userService.queryRolesByUsername(username);
        info.setRoles(roles);
        // 查询用户权限
        Set<String> permissions = userService.queryPermissionsByUsername(username);
        info.setStringPermissions(permissions);
        return info;
    }
    
    // 认证逻辑
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) 
            throws AuthenticationException {
        String username = (String) token.getPrincipal();
        User user = userService.queryByUsername(username);
        if (user == null) {
            throw new UnknownAccountException("用户不存在");
        }
        return new SimpleAuthenticationInfo(
            user.getUsername(), 
            user.getPassword(), 
            ByteSource.Util.bytes(user.getSalt()),
            getName()
        );
    }
}

4.2 Spring配置类

@Configuration
public class ShiroConfig {
    // 1. 创建Realm
    @Bean
    public CustomRealm customRealm() {
        CustomRealm realm = new CustomRealm();
        // 配置加密算法
        HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
        matcher.setHashAlgorithmName("MD5");
        matcher.setHashIterations(1024);
        realm.setCredentialsMatcher(matcher);
        return realm;
    }
    
    // 2. 创建SecurityManager
    @Bean
    public SecurityManager securityManager(CustomRealm realm) {
        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
        manager.setRealm(realm);
        // 配置会话管理器
        manager.setSessionManager(sessionManager());
        // 配置缓存管理器
        manager.setCacheManager(cacheManager());
        return manager;
    }
    
    // 3. 配置Shiro过滤器
    @Bean
    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean factory = new ShiroFilterFactoryBean();
        factory.setSecurityManager(securityManager);
        
        // 配置URL拦截规则
        Map<String, String> filterMap = new LinkedHashMap<>();
        filterMap.put("/login", "anon");          // 登录页匿名访问
        filterMap.put("/css/**", "anon");         // 静态资源匿名访问
        filterMap.put("/admin/**", "roles[ADMIN]");// 管理员角色访问
        filterMap.put("/user/**", "perms[user:view]");// 用户权限访问
        filterMap.put("/**", "authc");            // 其他路径需认证
        
        factory.setFilterChainDefinitionMap(filterMap);
        factory.setLoginUrl("/login");            // 未认证跳转页
        factory.setUnauthorizedUrl("/unauth");    // 未授权跳转页
        return factory;
    }
    
    // 4. 配置会话管理器
    @Bean
    public SessionManager sessionManager() {
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        sessionManager.setGlobalSessionTimeout(3600000); // 1小时超时
        sessionManager.setSessionDAO(new MemorySessionDAO());
        return sessionManager;
    }
    
    // 5. 配置缓存管理器
    @Bean
    public CacheManager cacheManager() {
        return new MemoryConstrainedCacheManager();
    }
}

4.3 登录控制器实现

@Controller
public class LoginController {
    @PostMapping("/login")
    public String login(String username, String password) {
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        try {
            subject.login(token);
            return "redirect:/index";
        } catch (UnknownAccountException e) {
            model.addAttribute("error", "用户名不存在");
            return "login";
        } catch (IncorrectCredentialsException e) {
            model.addAttribute("error", "密码错误");
            return "login";
        }
    }
    
    @GetMapping("/unauth")
    @ResponseBody
    public ResultVO unauth() {
        return ResultVO.fail(403, "没有访问权限");
    }
}

5. 高级特性配置

5.1 会话共享(分布式场景)

<!-- 配置Redis会话DAO -->
<bean id="redisSessionDAO" class="org.crazycake.shiro.RedisSessionDAO">
    <property name="redisManager" ref="redisManager"/>
</bean>
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
    <property name="sessionDAO" ref="redisSessionDAO"/>
</bean>

5.2 记住我功能

// 在ShiroFilterFactoryBean中添加
factory.setRememberMeParam("rememberMe");
factory.setSuccessUrl("/index");

// 登录时设置记住我
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
token.setRememberMe(true);
subject.login(token);

6. 常见问题解决方案

问题场景解决方案代码示例
密码加密存储使用HashedCredentialsMatchermatcher.setHashAlgorithmName("MD5")
权限动态更新调用realm.clearCache()SecurityUtils.getSubject().getSession().stop()
单点登录集成集成CAS客户端casFilter.setServerUrlPrefix("https://cas.example.com/cas")
跨域请求处理自定义CORS过滤器实现javax.servlet.Filter接口处理OPTIONS请求

7. 性能优化策略

  1. 缓存优化:使用Ehcache替代内存缓存

    <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
        <property name="cacheManagerConfigFile" value="classpath:ehcache.xml"/>
    </bean>
    
  2. 会话优化:设置合理的超时时间和清理策略

    sessionManager.setSessionValidationInterval(1800000); // 30分钟验证一次
    sessionManager.setSessionValidationSchedulerEnabled(true);
    
  3. SQL优化:权限查询使用批量操作

    -- 批量查询用户角色
    SELECT r.role_code FROM sys_user_role ur
    LEFT JOIN sys_role r ON ur.role_id = r.id
    WHERE ur.user_id = #{userId}
    

8. 与Spring Security对比分析

mermaid

特性ShiroSpring Security
上手难度简单复杂
配置方式XML/JavaConfigJavaConfig为主
OAuth集成需扩展原生支持
密码加密内置多种算法需自定义
社区支持中等活跃

9. 总结与未来展望

通过本文的系统化讲解,你已掌握Shiro与Spring集成的完整流程,包括:

  1. 环境搭建与依赖配置
  2. 核心组件的实现原理
  3. 认证授权的代码实现
  4. 高级特性与性能优化

建议后续深入学习:

  • Shiro的分布式会话解决方案
  • 基于JWT的无状态认证改造
  • 安全审计日志与异常监控

收藏本文,关注项目更新,获取更多Spring生态实战指南!

【免费下载链接】spring-reading 涵盖了 Spring 框架的核心概念和关键功能,包括控制反转(IOC)容器的使用,面向切面编程(AOP)的原理与实践,事务管理的方式与实现,Spring MVC 的流程与控制器工作机制,以及 Spring 中数据访问、安全、Boot 自动配置等方面的深入研究。此外,它还包含了 Spring 事件机制的应用、高级主题如缓存抽象和响应式编程,以及对 Spring 源码的编程风格与设计模式的深入探讨。 【免费下载链接】spring-reading 项目地址: https://gitcode.com/GitHub_Trending/sp/spring-reading

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值