Shiro作为一个强大且易用的Java安全框架,广泛应用于身份认证、授权、加密和会话管理等领域,在实际开发中,Shiro与数据库的连接是实现用户认证和授权的核心环节,下面将详细介绍Shiro如何连接数据库,包括配置、Realm实现、密码加密等关键内容。

Shiro与数据库连接的基本原理
Shiro本身不直接操作数据库,而是通过Realm(领域)组件来间接访问数据库,Realm是Shiro与安全数据之间的桥梁,负责获取认证和授权信息,当用户进行登录操作时,Shiro会调用Realm的认证方法,Realm从数据库中查询用户信息(如用户名、密码、权限等),并返回给Shiro进行验证,Shiro连接数据库的关键在于正确配置和实现Realm。
数据库连接的配置
在Shiro中,数据库连接通常通过数据源(DataSource)来实现,常见的配置方式有两种:基于XML的配置和基于Java代码的配置。
基于XML的配置
在shiro.ini或shiro.xml文件中,可以通过dataSource属性指定数据源。
dataSource = com.zaxxer.hikari.HikariDataSource dataSource.driverClassName = com.mysql.cj.jdbc.Driver dataSource.jdbcUrl = jdbc:mysql://localhost:3306/shiro_db dataSource.username = root dataSource.password = 123456
这里使用了HikariCP作为连接池,也可以使用其他连接池如Druid。
基于Java代码的配置
在Spring Boot环境中,可以通过配置类注入数据源。
@Configuration
public class ShiroConfig {
@Bean
public DataSource dataSource() {
HikariDataSource dataSource = new HikariDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/shiro_db");
dataSource.setUsername("root");
dataSource.setPassword("123456");
return dataSource;
}
} Realm的实现与数据库交互
Realm是Shiro与数据库交互的核心组件,需要继承AuthorizingRealm并实现两个方法:doGetAuthenticationInfo(认证)和doGetAuthorizationInfo(授权)。

认证方法实现
doGetAuthenticationInfo方法用于验证用户身份。
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String username = (String) token.getPrincipal();
// 从数据库查询用户信息
User user = userMapper.findByUsername(username);
if (user == null) {
throw new UnknownAccountException("用户不存在");
}
// 返回认证信息,包括用户名、密码和realm名称
return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName());
} 授权方法实现
doGetAuthorizationInfo方法用于获取用户权限。
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String username = (String) principals.getPrimaryPrincipal();
// 从数据库查询用户权限
List<String> permissions = permissionMapper.findPermissionsByUsername(username);
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
authorizationInfo.addStringPermissions(permissions);
return authorizationInfo;
} 密码加密与验证
为了安全,数据库中的用户密码通常需要加密存储,Shiro提供了HashedCredentialsMatcher用于密码加密和验证。
密码加密
在用户注册或修改密码时,使用Shiro提供的加密工具类。
String password = "123456";
String hashedPassword = new SimpleHash("md5", password, null, 1024).toHex();
// 将hashedPassword存入数据库 密码验证配置
在Realm中配置HashedCredentialsMatcher:
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher() {
HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();
matcher.setHashAlgorithmName("md5"); // 加密算法
matcher.setHashIterations(1024); // 加密次数
return matcher;
}
@Bean
public UserRealm userRealm(HashedCredentialsMatcher matcher) {
UserRealm realm = new UserRealm();
realm.setCredentialsMatcher(matcher);
return realm;
} 会话管理
Shiro还提供了会话管理功能,可以通过配置会话管理器和会话存储来实现与数据库的集成,使用EnterpriseCacheSessionDAO将会话数据存储在数据库中:

@Bean
public SessionManager sessionManager() {
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
sessionManager.setSessionDAO(new EnterpriseCacheSessionDAO());
return sessionManager;
} Shiro通过Realm组件与数据库交互,实现用户认证和授权,配置数据源、实现Realm、处理密码加密是关键步骤,通过合理配置,Shiro可以高效、安全地管理用户数据。
FAQs
Q1:Shiro是否支持多数据源配置?
A1:支持,可以通过自定义Realm实现多数据源逻辑,或在Shiro配置中动态切换数据源,根据用户类型选择不同的数据源进行查询。
Q2:Shiro的Realm如何实现动态权限更新?
A2:可以通过缓存机制(如Redis)或定时任务动态刷新权限信息,在doGetAuthorizationInfo方法中,每次调用时从数据库或缓存中获取最新权限,确保权限的实时性。
【版权声明】:本站所有内容均来自网络,若无意侵犯到您的权利,请及时与我们联系将尽快删除相关内容!
发表回复