核心鉴权方式
Servlet Filter(基础方案)
public class AuthFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; // 1. 检查用户是否登录(认证) HttpSession session = req.getSession(false); if (session == null || session.getAttribute("user") == null) { res.sendRedirect("/login"); return; } // 2. 鉴权逻辑:检查用户角色/权限 User user = (User) session.getAttribute("user"); if (!user.hasPermission(req.getRequestURI())) { res.sendError(HttpServletResponse.SC_FORBIDDEN, "无访问权限"); return; } chain.doFilter(request, response); // 放行请求 } }
配置 web.xml:
<filter> <filter-name>AuthFilter</filter-name> <filter-class>com.example.AuthFilter</filter-class> </filter> <filter-mapping> <filter-name>AuthFilter</filter-name> <url-pattern>/admin/*</url-pattern> <!-- 只拦截管理路径 --> </filter-mapping>
Spring Security(企业级方案)
步骤:
-
添加依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency>
-
配置权限规则:
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/public/**").permitAll() // 公开资源 .antMatchers("/admin/**").hasRole("ADMIN") // 需ADMIN角色 .antMatchers("/user/**").hasAnyRole("USER", "ADMIN") .anyRequest().authenticated() // 其他路径需登录 .and() .formLogin(); // 启用登录页 } }
-
自定义权限校验(如方法级鉴权):
@Service public class UserService { @PreAuthorize("hasRole('ADMIN') or #userId == authentication.principal.id") public void updateUser(Long userId, UserData data) { // 仅管理员或用户本人可操作 } }
RBAC模型(权限控制基石)
基于角色的访问控制(Role-Based Access Control)是行业标准:
- 用户(User):系统使用者
- 角色(Role):权限集合(如ADMIN、USER)
- 权限(Permission):具体操作(如user:delete、order:query)
graph LR User -- 属于 --> Role Role -- 拥有 --> Permission Permission -- 控制 --> Resource[API/页面]
JWT鉴权(前后端分离方案)
-
登录后生成Token:
String jwt = Jwts.builder() .setSubject(username) .claim("roles", user.getRoles()) // 嵌入角色信息 .setExpiration(new Date(System.currentTimeMillis() + 3600000)) .signWith(SignatureAlgorithm.HS512, "secretKey") .compact();
-
请求校验(Filter中实现):
String token = request.getHeader("Authorization"); Claims claims = Jwts.parser() .setSigningKey("secretKey") .parseClaimsJws(token) .getBody(); String username = claims.getSubject(); List<String> roles = claims.get("roles", List.class); // 将角色信息存入SecurityContextHolder
安全最佳实践
- 最小权限原则:用户仅拥有必要权限
- 防范越权:
- 垂直越权:普通用户访问管理员接口 → 用角色校验拦截
- 水平越权:用户A修改用户B的数据 → 校验数据归属(如
@PreAuthorize("#userId == principal.id")
)
- 敏感操作日志:记录关键操作(删除、权限变更)
- 定期更换密钥:JWT签名密钥至少每季度更换
- 避免路径硬编码:使用权限标识符而非URL匹配(如
hasPermission('user:delete')
)
常见问题解决方案
- 权限动态变更:实时生效需结合Redis(将权限缓存并设置过期时间)
- 分布式鉴权:JWT适合无状态系统,Session方案需用Spring Session + Redis共享
- CSRF防护:Spring Security默认启用,表单操作需携带
_csrf
令牌
JavaWeb鉴权需结合场景选择方案:
- 单体应用:Spring Security + Session
- 前后端分离:Spring Security + JWT
- 微服务架构:OAuth2.0 + 网关统一鉴权
引用说明: 参考Spring Security官方文档(spring.io/projects/spring-security)及OWASP访问控制指南(owasp.org/www-project-authorization),技术实现基于JDK 11+与Spring Boot 2.7,遵循MIT开源协议。
原创文章,发布者:酷盾叔,转转请注明出处:https://www.kd.cn/ask/32622.html