如何在SpringBoot整合Apache Shiro?

Apache Shiro是一款与Spring Security类似的功能强大的Java安全框架,但相比较于Spring Security,Apache Shiro更加轻量化且易于集成。在Spring Boot中集成Apache Shiro可以为应用程序提供授权认证、会话加密、会话管理等功能。下面我们就来详细介绍一下如何在Spring Boot集成Apache Shiro。
环境准备
引入依赖
首先,我们需要在在pom.xml中添加Apache Shiro相关依赖,如下所示。
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.9.1</version>
</dependency>
具体实现
在Apache Shiro提供了Realm、SecurityManager、ShiroFilter等组件,如下所示。
- Realm:定义认证和授权的规则。
- SecurityManager:Shiro的核心,用于管理所有安全操作。
- ShiroFilter:负责拦截请求并执行相应的认证和授权检查。
接下来我们就分别配置这些组件来实现Apache Shiro安全认证。
配置Realm
Realm是用于在Apache Shiro中连接数据源并进行用户认证与授权类。所以,这里我们可以创建一个自定义Realm类,假设在数据库中存储了用户信息,如下所示。
public class MyRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
// 假设添加一些角色和权限(实际可从数据库加载)
authorizationInfo.addRole("admin");
authorizationInfo.addStringPermission("user:read");
return authorizationInfo;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken upToken = (UsernamePasswordToken) token;
String username = upToken.getUsername();
// 假设从数据库查找用户信息
if ("user".equals(username)) {
return new SimpleAuthenticationInfo(username, "password123", getName());
} else {
throw new AuthenticationException("用户不存在");
}
}
}
在这个自定义的Realm中,我们可以通过doGetAuthenticationInfo方法来实现用户的认证操作,通过doGetAuthorizationInfo方法用来进行用户的授权操作。
配置SecurityManager
定义完成之后,我们需要配置安全管理器,在ShiroConfig配置类中配置SecurityManager和Realm,如下所示。
@Configuration
public class ShiroConfig {
@Bean
public MyRealm myRealm() {
return new MyRealm();
}
@Bean
public SecurityManager securityManager(MyRealm myRealm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myRealm);
return securityManager;
}
@Bean
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
// 配置拦截规则
Map<String, String> filterMap = new HashMap<>();
filterMap.put("/login", "anon"); // 允许匿名访问
filterMap.put("/logout", "logout");
filterMap.put("/**", "authc"); // 其他请求需要认证
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
// 配置登录和未授权跳转的页面
shiroFilterFactoryBean.setLoginUrl("/login");
shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");
return shiroFilterFactoryBean;
}
}
在这个配置中,我们配置了ShiroFilterFactoryBean的过滤规则,用来指定哪些路径需要授权认证,哪些路径不需要进行授权认证,而loginUrl和unauthorizedUrl用于定义默认的登录和未授权页面。
配置会话管理
在分布式系统中Shiro还提供了会话管理功能,我们可以通过在ShiroConfig中配置SessionManager来支持自定义的会话管理操作。如下所示。
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.apache.shiro.session.mgt.SessionManager;
@Bean
public SessionManager sessionManager() {
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
sessionManager.setGlobalSessionTimeout(1800000); // 设置会话超时时间(单位:毫秒)
return sessionManager;
}
创建登录测试接口
配置完成之后,我们就可以创建一个简单的登录接口类,用来测试通过Shiro进行用户授权等操作。如下所示。
@RestController
public class LoginController {
@PostMapping("/login")
public String login(@RequestParam("username") String username,
@RequestParam("password") String password) {
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
try {
subject.login(token);
return "登录成功";
} catch (Exception e) {
return "登录失败:" + e.getMessage();
}
}
@GetMapping("/logout")
public String logout() {
SecurityUtils.getSubject().logout();
return "已登出";
}
}
在这个Controller中,定义了两个端点,其中/login会获取用户提交的用户名和密码,并尝试通过Shiro进行认证,而/logout则是用来退出登录的调用端点。
总结
通过上面的实现操作,我们就可以实现Shiro安全框架与Spring Boot的整合,在实际的使用场景中,我们可以对其进行进一步的优化升级,例如可以进一步配置缓存、密码加密、权限动态加载等,来构建一个更完整的安全体系。有兴趣的读者可以基于以上的项目对其进行扩展。相关问题我们可以在评论区讨论。