Zc提问: jwt过滤器
Ai回答: 以下是关于JWT过滤器的分步指南和示例代码:
1、添加依赖
在`pom.xml`中添加JWT库(如jjwt)和Spring Security依赖:
xml
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.5</version>
</dependency>
2、JWT工具类
java
import io.jsonwebtoken.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
@Component
public class JwtUtil {
@Value(${jwt.secret})
private String SECRET_KEY;
@Value(${jwt.expiration})
private long EXPIRATION;
// 提取用户名
public String extractUsername(String token) {
return extractClaim(token, Claims::getSubject);
}
// 提取过期时间
public Date extractExpiration(String token) {
return extractClaim(token, Claims::getExpiration);
}
// 提取特定声明
public <T> T extractClaim(String token, Function<Claims, T> claimsResolver) {
final Claims claims = extractAllClaims(token);
return claimsResolver.apply(claims);
}
// 解析所有声明
private Claims extractAllClaims(String token) {
return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();
}
// 生成令牌
public String generateToken(UserDetails userDetails) {
Map<String, Object> claims = new HashMap<>();
return createToken(claims, userDetails.getUsername());
}
// 创建令牌
private String createToken(Map<String, Object> claims, String subject) {
return Jwts.builder().setClaims(claims)
.setSubject(subject)
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION))
.signWith(SignatureAlgorithm.HS512, SECRET_KEY)
.compact();
}
// 验证令牌是否有效
public Boolean validateToken(String token, UserDetails userDetails) {
final String username = extractUsername(token);
return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
}
// 检查令牌是否过期
private Boolean isTokenExpired(String token) {
return extractExpiration(token).before(new Date());
}
}
3、JWT过滤器
java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class JwtFilter extends OncePerRequestFilter {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private JwtUtil jwtUtil;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
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);
try {
username = jwtUtil.extractUsername(jwt);
} catch (JwtException e) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, Invalid JWT token);
return;
}
}
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
if (jwtUtil.validateToken(jwt, userDetails)) {
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}
filterChain.doFilter(request, response);
}
}
4、安全配置
java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private JwtFilter jwtFilter;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
@Bean
public PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance(); // 生产环境应使用更强的密码编码器
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)
.authorizeRequests()
.antMatchers(/authenticate).permitAll()
.anyRequest().authenticated();
}
}
5、登录接口示例
java
@RestController
public class AuthController {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private JwtUtil jwtUtil;
@PostMapping(/authenticate)
public ResponseEntity<?> createAuthenticationToken(@RequestBody AuthRequest authRequest) throws Exception {
try {
authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(authRequest.getUsername(), authRequest.getPassword())
);
} catch (BadCredentialsException e) {
throw new Exception(Incorrect username or password, e);
}
final UserDetails userDetails = userDetailsService.loadUserByUsername(authRequest.getUsername());
final String jwt = jwtUtil.generateToken(userDetails);
return ResponseEntity.ok(new AuthResponse(jwt));
}
}
6、配置属性
在`application.properties`中添加:
properties
jwt.secret=your-secret-key
jwt.expiration=86400000 24小时
7、测试步骤
1、发送POST请求到`/authenticate`获取JWT。
2、使用返回的JWT在其他请求的`Authorization`头中添加`Bearer <token>`。
3、访问受保护的资源,验证过滤器是否正常工作。
注意事项
密钥安全:避免硬编码密钥,使用环境变量或配置中心。
令牌刷新:实现刷新令牌机制以增强安全性。
异常处理:全局异常处理器应捕获`JwtException`并返回适当的HTTP状态码。
CORS配置:确保前端请求不会因跨域问题被阻止。
通过以上步骤,可以实现一个基本的JWT过滤器,用于保护Spring Boot应用的API端点。
商家广告:
🏬产品: 洁净棚厂家 耐高温高效过滤器400度
📱咨询:13560190937 李经理
✉️咨询:649099016@qq.com
🔗网址:www.gdznjh.com
🏢公司:广州梓成净化设备制造有限公司
🏭厂址:广州番禺大龙街道长沙路34号北门5栋厂房
0
IP地址: 208.80.32.176
搜索次数: 1334
提问时间: 2025-05-11 16:01:49
热门提问:
过滤棉耐高温吗
简易砂石过滤器
厂家名单
merv13过滤器
3d,过滤器
井水农村过滤设备
货淋通道风淋室
天津风淋室厂家
液槽高效过滤器应用场景
袋型过滤器
净化车间制造商
纸框初效板式过滤器
af高效过滤器
滨特尔前置过滤器好不好
无尘车间电动门
北京空气过滤器公司
过滤器行业标准
无尘车间需要注意什么
芬特过滤器工作原理
进风过滤装置
友情链接:
一站式搜索平台
検索エンジンのソースコード
温馨提示:
本站所有问答由Ai自动创作,若有误差请用“联系”里面信息通知我们人工修改或删除。
技术支持:
本站由豌豆Ai提供技术支持,使用的最新版:《豌豆Ai站群搜索引擎系统 V.25.05.20》搭建本站。