Shiro整合实战:Spring Boot与数据库集成指南
Shiro扩展与集成实战指南
一、Spring/Spring Boot整合
自动化配置原理
Spring Boot通过ShiroAutoConfiguration
自动配置核心组件,开发者只需定义Realm
和SecurityManager
即可完成基础整合。
@Configuration
public class ShiroConfig {
@Bean
public Realm customRealm() {
return new CustomRealm();
}
@Bean
public SecurityManager securityManager(Realm realm) {
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
manager.setRealm(realm);
return manager;
}
}
实践建议:
- 使用
@DependsOn
注解明确Bean依赖顺序 通过
application.yml
配置Shiro基础参数:shiro: enabled: true loginUrl: /login successUrl: /home
二、Web集成机制
Filter链工作原理
Shiro通过过滤器链实现URL级安全控制,典型配置示例:
@Bean
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean factory = new ShiroFilterFactoryBean();
factory.setSecurityManager(securityManager);
Map<String, String> filterMap = new LinkedHashMap<>();
filterMap.put("/static/**", "anon");
filterMap.put("/login", "anon");
filterMap.put("/admin/**", "authc, roles[admin]");
filterMap.put("/**", "user");
factory.setFilterChainDefinitionMap(filterMap);
return factory;
}
过滤器类型:
anon
:匿名访问authc
:需要认证user
:记住我用户可访问perms
:需要特定权限
三、数据库集成方案
JDBC Realm配置
public class JdbcRealm extends AuthorizingRealm {
@Autowired
private DataSource dataSource;
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) {
String sql = "SELECT password, salt FROM users WHERE username = ?";
try (Connection conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
// 执行查询并构建AuthenticationInfo
}
}
}
性能优化:
- 实现
CachingRealm
接口启用缓存 - 使用
SimpleAuthenticationInfo
传递盐值 密码比对建议:
ByteSource salt = ByteSource.Util.bytes(user.getSalt()); return new SimpleAuthenticationInfo( username, user.getPassword(), salt, getName() );
四、OAuth2集成策略
适配流程
自定义OAuth2Token:
public class OAuth2Token implements AuthenticationToken { private String accessToken; // getters/setters... }
实现OAuth2Realm:
public class OAuth2Realm extends AuthorizingRealm { public boolean supports(AuthenticationToken token) { return token instanceof OAuth2Token; } protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) { String accessToken = (String) token.getPrincipal(); // 调用OAuth2 provider验证token } }
关键配置:
@Bean
public DefaultFilterChainManager filterChainManager() {
DefaultFilterChainManager manager = new DefaultFilterChainManager();
manager.addFilter("oauth2", new OAuth2Filter());
return manager;
}
五、多Realm协同方案
策略配置示例
@Bean
public SecurityManager securityManager(List<Realm> realms) {
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
ModularRealmAuthenticator authenticator = new ModularRealmAuthenticator();
authenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy());
manager.setAuthenticator(authenticator);
manager.setRealms(realms); // 注入多个Realm
return manager;
}
典型组合场景:
- 本地数据库Realm + LDAPRealm
- JWTRealm + OAuth2Realm
- 主备Realm策略(FirstSuccessfulStrategy)
优先级控制:
@Bean
@Order(1)
public Realm primaryRealm() {
return new PrimaryRealm();
}
@Bean
@Order(2)
public Realm secondaryRealm() {
return new SecondaryRealm();
}
最佳实践总结
配置优化:
- 生产环境务必启用缓存
- 敏感URL应使用SSL要求配置
安全建议:
@Bean public RememberMeManager rememberMeManager() { CookieRememberMeManager manager = new CookieRememberMeManager(); manager.setCipherKey(Base64.decode("secureKey...")); return manager; }
调试技巧:
# application.properties logging.level.org.apache.shiro=DEBUG
扩展方向:
- 实现
SessionDAO
集成Redis - 自定义
PermissionResolver
支持复杂权限逻辑
- 实现
通过合理组合这些集成方案,可以构建既安全又灵活的企业级权限系统。
评论已关闭