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端点。


商家广告

F8中效袋式过滤器

🏬产品洁净棚厂家  耐高温高效过滤器400度 

📱咨询13560190937 李经理

✉️咨询649099016@qq.com

🔍微信
wx

🔗网址www.gdznjh.com

🏢公司广州梓成净化设备制造有限公司

🏭厂址广州番禺大龙街道长沙路34号北门5栋厂房


0

IP地址: 208.80.32.176

搜索次数: 1334

提问时间: 2025-05-11 16:01:49

热门作画
升降传递窗安装图y型过滤器标准图集

热门提问
过滤棉耐高温吗
简易砂石过滤器
厂家名单
merv13过滤器
3d,过滤器
井水农村过滤设备
货淋通道风淋室
天津风淋室厂家
液槽高效过滤器应用场景
袋型过滤器
净化车间制造商
纸框初效板式过滤器
af高效过滤器
滨特尔前置过滤器好不好
无尘车间电动门
北京空气过滤器公司
过滤器行业标准
无尘车间需要注意什么
芬特过滤器工作原理
进风过滤装置

友情链接
一站式搜索平台  検索エンジンのソースコード 

站长工具
whois查询 搜索

温馨提示
本站所有问答由Ai自动创作,若有误差请用“联系”里面信息通知我们人工修改或删除。

技术支持
本站由豌豆Ai提供技术支持,使用的最新版:《豌豆Ai站群搜索引擎系统 V.25.05.20》搭建本站。

上一篇102691027010271下一篇