别再乱配Shiro了!Spring Boot整合Shiro实现Token登录,这份配置清单请收好
Spring Boot与Shiro的Token认证实践指南在当今的Web应用开发中认证与授权机制是保障系统安全的核心组件。许多开发者选择Apache Shiro作为安全框架但在与Spring Boot整合时尤其是采用Token认证模式时常常会遇到各种配置难题。本文将系统性地梳理Spring Boot整合Shiro实现Token认证的关键配置点帮助开发者避开常见陷阱。1. 基础环境搭建在开始配置之前我们需要确保项目基础环境正确搭建。创建一个新的Spring Boot项目并添加以下核心依赖dependencies !-- Spring Boot Starter Web -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency !-- Apache Shiro -- dependency groupIdorg.apache.shiro/groupId artifactIdshiro-spring-boot-web-starter/artifactId version1.9.0/version /dependency !-- JWT支持可选 -- dependency groupIdio.jsonwebtoken/groupId artifactIdjjwt/artifactId version0.9.1/version /dependency /dependencies关键配置检查清单确保Shiro版本与Spring Boot版本兼容如果使用JWT选择合适的JWT库版本检查依赖冲突特别是与Spring Security的冲突2. Shiro核心配置详解Shiro的核心配置主要集中在ShiroConfig类中这个类需要包含以下几个关键Bean的定义Configuration public class ShiroConfig { Bean public SecurityManager securityManager(CustomRealm customRealm) { DefaultWebSecurityManager securityManager new DefaultWebSecurityManager(); securityManager.setRealm(customRealm); securityManager.setSessionManager(sessionManager()); return securityManager; } Bean public SessionManager sessionManager() { DefaultWebSessionManager sessionManager new DefaultWebSessionManager(); sessionManager.setSessionValidationSchedulerEnabled(true); sessionManager.setSessionIdUrlRewritingEnabled(false); return sessionManager; } Bean public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) { ShiroFilterFactoryBean shiroFilter new ShiroFilterFactoryBean(); shiroFilter.setSecurityManager(securityManager); // 配置自定义过滤器 MapString, Filter filters new HashMap(); filters.put(tokenAuth, new TokenAuthenticationFilter()); shiroFilter.setFilters(filters); // 配置拦截规则 MapString, String filterMap new LinkedHashMap(); filterMap.put(/api/login, anon); filterMap.put(/api/public/**, anon); filterMap.put(/api/**, tokenAuth); shiroFilter.setFilterChainDefinitionMap(filterMap); return shiroFilter; } }关键点解析配置项说明常见问题SecurityManagerShiro安全核心必须正确设置Realm和SessionManagerSessionManager会话管理禁用URL重写可提高安全性ShiroFilterFactoryBean请求过滤拦截规则顺序很重要3. 自定义Token认证实现Token认证的核心在于自定义Realm和Filter。以下是实现Token认证的关键组件3.1 自定义Realm实现public class CustomRealm extends AuthorizingRealm { Override public boolean supports(AuthenticationToken token) { return token instanceof JwtToken; } Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { String username (String) principals.getPrimaryPrincipal(); SimpleAuthorizationInfo info new SimpleAuthorizationInfo(); // 添加角色和权限 info.addRoles(getRolesForUser(username)); info.addStringPermissions(getPermissionsForUser(username)); return info; } Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { JwtToken jwtToken (JwtToken) token; String jwt (String) jwtToken.getCredentials(); // 验证JWT有效性 if (!validateToken(jwt)) { throw new AuthenticationException(Invalid token); } String username extractUsernameFromToken(jwt); return new SimpleAuthenticationInfo(username, jwt, getName()); } }3.2 自定义Token过滤器public class TokenAuthenticationFilter extends AuthenticatingFilter { Override protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) { HttpServletRequest httpRequest (HttpServletRequest) request; String token httpRequest.getHeader(Authorization); if (token null || !token.startsWith(Bearer )) { return null; } return new JwtToken(token.substring(7)); } Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { if (executeLogin(request, response)) { return true; } ((HttpServletResponse) response).sendError(HttpServletResponse.SC_UNAUTHORIZED); return false; } }Token处理流程客户端发送请求携带Token过滤器提取Token并创建认证TokenShiro调用Realm进行认证认证成功后进行授权检查请求继续处理或返回错误4. 登录与Token生成登录接口需要生成Token并返回给客户端RestController RequestMapping(/api) public class AuthController { PostMapping(/login) public ResponseEntity? login(RequestBody LoginRequest request) { // 验证用户名密码 Subject subject SecurityUtils.getSubject(); UsernamePasswordToken token new UsernamePasswordToken( request.getUsername(), request.getPassword() ); try { subject.login(token); // 生成JWT String jwtToken Jwts.builder() .setSubject(request.getUsername()) .setExpiration(new Date(System.currentTimeMillis() 3600000)) .signWith(SignatureAlgorithm.HS512, secretKey) .compact(); return ResponseEntity.ok(new AuthResponse(jwtToken)); } catch (AuthenticationException e) { return ResponseEntity.status(401).body(Invalid credentials); } } }Token生成最佳实践设置合理的过期时间使用安全的签名算法不要在Token中存储敏感信息考虑使用Refresh Token机制5. 高级配置与优化5.1 集群环境支持在集群环境中需要考虑Session共享问题。可以通过以下方式实现Bean ConditionalOnProperty(name cluster.enabled, havingValue true) public SessionManager clusterSessionManager(RedisTemplateString, Object redisTemplate) { RedisSessionDAO sessionDAO new RedisSessionDAO(); sessionDAO.setRedisTemplate(redisTemplate); DefaultWebSessionManager sessionManager new DefaultWebSessionManager(); sessionManager.setSessionDAO(sessionDAO); return sessionManager; }5.2 性能优化对于高并发场景可以考虑以下优化措施缓存授权信息在Realm中实现缓存机制Token黑名单实现Token失效机制异步验证对于耗时操作采用异步方式Bean public CacheManager shiroCacheManager(RedisTemplateString, Object redisTemplate) { RedisCacheManager cacheManager new RedisCacheManager(); cacheManager.setRedisTemplate(redisTemplate); return cacheManager; } Bean public SecurityManager securityManager(CustomRealm customRealm, CacheManager cacheManager) { DefaultWebSecurityManager securityManager new DefaultWebSecurityManager(); securityManager.setRealm(customRealm); securityManager.setCacheManager(cacheManager); return securityManager; }6. 常见问题排查在实际项目中经常会遇到以下问题Filter不生效检查Filter是否注册到ShiroFilterFactoryBean确认拦截规则配置正确依赖注入失败确保Filter是通过ShiroFilterFactoryBean注册考虑使用静态方法获取Bean跨域问题确保CORS配置在Shiro过滤器之前执行在Filter中正确处理OPTIONS请求public class TokenAuthenticationFilter extends AuthenticatingFilter { Override protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) { if (((HttpServletRequest) request).getMethod().equals(OPTIONS)) { return true; } return super.isAccessAllowed(request, response, mappedValue); } }在实际项目中整合Spring Boot和Shiro实现Token认证时关键是要理解各个组件的职责和交互方式。通过本文提供的配置清单和最佳实践开发者可以快速搭建安全可靠的认证系统同时避免常见的配置错误。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2521409.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!