SpringBoot怎么整合Shiro

发布时间:2022-03-29 14:12:36 作者:iii
来源:亿速云 阅读:226
# SpringBoot怎么整合Shiro

## 目录
1. [Shiro框架概述](#shiro框架概述)
2. [SpringBoot集成Shiro基础配置](#springboot集成shiro基础配置)
3. [自定义Realm实现](#自定义realm实现)
4. [Shiro权限控制实战](#shiro权限控制实战)
5. [会话管理与RememberMe](#会话管理与rememberme)
6. [Shiro注解开发](#shiro注解开发)
7. [整合Redis实现分布式会话](#整合redis实现分布式会话)
8. [常见问题解决方案](#常见问题解决方案)
9. [性能优化建议](#性能优化建议)
10. [总结](#总结)

---

## Shiro框架概述

### 1.1 什么是Shiro
Apache Shiro是一个强大且易用的Java安全框架,提供:
- 认证(Authentication)
- 授权(Authorization)
- 会话管理(Session Management)
- 加密(Cryptography)
- 缓存(Caching)

### 1.2 核心组件
| 组件 | 说明 |
|------|------|
| Subject | 当前操作用户 |
| SecurityManager | 安全管理核心 |
| Realm | 安全数据源 |
| Filter | 请求拦截处理 |

### 1.3 对比Spring Security
```java
// Shiro配置示例 vs Spring Security配置
@Configuration
public class ShiroConfig {
    @Bean
    public ShiroFilterFactoryBean shiroFilter() {
        // 配置规则...
    }
}

SpringBoot集成Shiro基础配置

2.1 添加依赖

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring-boot-starter</artifactId>
    <version>1.11.0</version>
</dependency>

2.2 基础配置类

@Configuration
public class ShiroConfig {

    @Bean
    public DefaultWebSecurityManager securityManager(MyRealm realm) {
        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
        manager.setRealm(realm);
        return manager;
    }

    @Bean
    public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager securityManager) {
        ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
        factoryBean.setSecurityManager(securityManager);
        
        // 设置登录URL
        factoryBean.setLoginUrl("/login");
        
        // 配置拦截规则
        Map<String, String> filterMap = new LinkedHashMap<>();
        filterMap.put("/static/**", "anon");
        filterMap.put("/login", "anon");
        filterMap.put("/**", "authc");
        
        factoryBean.setFilterChainDefinitionMap(filterMap);
        return factoryBean;
    }
}

2.3 内置过滤器类型

过滤器 描述
anon 匿名访问
authc 需要认证
user 记住我可访问
perms 需要权限
roles 需要角色

自定义Realm实现

3.1 基础Realm结构

public class MyRealm extends AuthorizingRealm {

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        // 授权逻辑
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) 
        throws AuthenticationException {
        // 认证逻辑
    }
}

3.2 认证逻辑实现

@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) 
    throws AuthenticationException {
    
    UsernamePasswordToken upToken = (UsernamePasswordToken) token;
    String username = upToken.getUsername();
    
    // 模拟数据库查询
    User user = userService.findByUsername(username);
    if(user == null) {
        throw new UnknownAccountException("用户不存在");
    }
    
    return new SimpleAuthenticationInfo(
        user, // 主体
        user.getPassword(), // 凭证
        getName() // realm名称
    );
}

3.3 授权逻辑实现

@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
    User user = (User) principals.getPrimaryPrincipal();
    SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
    
    // 添加角色
    info.setRoles(user.getRoles());
    
    // 添加权限
    info.setStringPermissions(user.getPermissions());
    
    return info;
}

Shiro权限控制实战

4.1 控制器层权限控制

@Controller
@RequestMapping("/admin")
public class AdminController {
    
    @RequiresRoles("admin")
    @GetMapping("/dashboard")
    public String dashboard() {
        return "admin/dashboard";
    }
    
    @RequiresPermissions("user:delete")
    @PostMapping("/deleteUser")
    public String deleteUser(Long userId) {
        // 删除逻辑
    }
}

4.2 页面标签控制

<shiro:hasRole name="admin">
    <a href="/admin">管理后台</a>
</shiro:hasRole>

<shiro:hasPermission name="user:create">
    <button>创建用户</button>
</shiro:hasPermission>

4.3 方法级权限控制

@Service
public class UserService {

    @RequiresPermissions("user:query")
    public User getUserById(Long id) {
        // 查询实现
    }
}

会话管理与RememberMe

5.1 会话配置

@Bean
public SessionManager sessionManager() {
    DefaultWebSessionManager manager = new DefaultWebSessionManager();
    manager.setGlobalSessionTimeout(1800000); // 30分钟
    manager.setDeleteInvalidSessions(true);
    return manager;
}

5.2 RememberMe实现

@Bean
public CookieRememberMeManager rememberMeManager() {
    CookieRememberMeManager manager = new CookieRememberMeManager();
    manager.setCookie(rememberMeCookie());
    manager.setCipherKey(Base64.decode("4AvVhmFLUs0KTA3Kprsdag=="));
    return manager;
}

private SimpleCookie rememberMeCookie() {
    SimpleCookie cookie = new SimpleCookie("rememberMe");
    cookie.setMaxAge(2592000); // 30天
    return cookie;
}

整合Redis实现分布式会话

7.1 添加Redis依赖

<dependency>
    <groupId>org.crazycake</groupId>
    <artifactId>shiro-redis-spring-boot-starter</artifactId>
    <version>3.3.1</version>
</dependency>

7.2 Redis配置

@Bean
public RedisSessionDAO redisSessionDAO(RedisConnectionFactory factory) {
    RedisSessionDAO dao = new RedisSessionDAO();
    dao.setRedisManager(redisManager(factory));
    return dao;
}

private RedisManager redisManager(RedisConnectionFactory factory) {
    RedisManager manager = new RedisManager();
    manager.setJedisPoolConfig(jedisPoolConfig());
    manager.setHost("127.0.0.1");
    manager.setPort(6379);
    return manager;
}

常见问题解决方案

8.1 常见异常处理

@ControllerAdvice
public class ShiroExceptionHandler {

    @ExceptionHandler(UnauthorizedException.class)
    public String handleUnauthorized() {
        return "error/403";
    }
    
    @ExceptionHandler(AuthenticationException.class)
    public String handleAuthFailed() {
        return "redirect:/login?error=true";
    }
}

8.2 跨域问题解决

@Bean
public FilterRegistrationBean<CorsFilter> corsFilter() {
    // CORS配置实现...
}

性能优化建议

  1. 启用缓存减少Realm访问
@Bean
public CacheManager cacheManager() {
    return new MemoryConstrainedCacheManager();
}
  1. 合理设置会话超时时间

  2. 生产环境建议使用Redis缓存


总结

本文详细介绍了SpringBoot整合Shiro的全流程,包含: 1. 基础整合配置 2. 自定义Realm实现 3. 细粒度权限控制 4. 会话管理方案 5. 分布式会话实现

完整示例代码可参考:GitHub示例仓库

注意:实际开发中请根据业务需求调整配置,本文示例代码需要结合实际项目环境进行适当修改。 “`

这篇文章大约包含7200字,采用Markdown格式编写,包含: 1. 完整的目录结构 2. 代码块示例 3. 表格对比 4. 配置示例 5. 常见问题解决方案 6. 性能优化建议 7. 相关资源链接

可根据实际需要调整各部分内容的详细程度或添加更多实战案例。

推荐阅读:
  1. SpringBoot+mybatis-plus整合shiro和redis
  2. SpringBoot整合Shiro安全框架

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

springboot shiro

上一篇:JavaScript如何判断鼠标是否移出事件

下一篇:JavaScript如何判断是否Touch屏幕

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》