Java实习生小渣的Spring Security初探:从权限控制到JWT实战
小渣与mentor的对话:引入Spring Security
小渣:mentor,最近项目中涉及用户权限控制,我听说Spring Security很强大,但我还没实际用过,能介绍下吗?
mentor:当然,Spring Security是Java生态中最常用的安全框架,支持认证、授权、CSRF防护等功能。我们今天就从基础权限控制开始,带你一步步理解并实战JWT认证。
一、Spring Security基础权限控制
Spring Security通过配置过滤器链来实现请求拦截和权限校验。下面是一个简单的配置示例:
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/public/**").permitAll() // 公开路径
.antMatchers("/admin/**").hasRole("ADMIN") // 只有ADMIN角色可访问
.anyRequest().authenticated() // 其他请求需登录
.and()
.formLogin()
.and()
.httpBasic();
}
}
这段代码中,我们定义了访问规则,确保敏感路径只有特定角色才能访问。
二、引入JWT实现无状态认证
传统的session认证在分布式环境下扩展性差,JWT(JSON Web Token)提供了无状态的认证方案。我们用Spring Security结合JWT来实现:
1. 生成JWT Token
public class JwtUtil {
private static final String SECRET_KEY = "mySecretKey";
public static String generateToken(String username) {
return Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 10)) // 10小时有效
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
}
2. 解析和验证JWT
public class JwtUtil {
// 省略生成方法
public static String extractUsername(String token) {
return Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody()
.getSubject();
}
public static boolean validateToken(String token, UserDetails userDetails) {
final String username = extractUsername(token);
return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
}
private static boolean isTokenExpired(String token) {
Date expiration = Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody()
.getExpiration();
return expiration.before(new Date());
}
}
3. Spring Security中集成JWT过滤器
public class JwtRequestFilter extends OncePerRequestFilter {
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
final String authorizationHeader = request.getHeader("Authorization");
String username = null;
String jwt = null;
if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
jwt = authorizationHeader.substring(7);
username = JwtUtil.extractUsername(jwt);
}
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
if (JwtUtil.validateToken(jwt, userDetails)) {
UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authToken);
}
}
chain.doFilter(request, response);
}
}
配置过滤器链时加入此过滤器即可完成JWT认证。
三、总结
通过今天的学习,小渣了解了Spring Security的基础权限控制机制,以及如何结合JWT实现无状态认证,适合分布式微服务环境。互联网大厂的安全策略非常重视认证与授权,掌握这些技术能帮助我们写出更安全、健壮的Java应用。
下一次,小渣计划和mentor探讨Spring Cloud微服务中的服务安全与服务注册认证,敬请期待!
希望本文对刚入门Spring Security的小伙伴有所帮助,欢迎留言交流~
4328

被折叠的 条评论
为什么被折叠?



