如何在 Spring Cloud Gateway 中启用 JWT 认证?
时间: 2024-12-17 19:29:33 浏览: 6
要在Spring Cloud Gateway中启用JWT(JSON Web Tokens)认证,你需要进行以下步骤:
1. 添加依赖:首先,在你的Maven或Gradle项目中添加Spring Security Web、Spring Cloud Gateway以及相关的JWT库。例如,如果你使用的是Spring Boot,你可以添加以下依赖到`pom.xml`(Maven)或`build.gradle`(Gradle):
```xml
<!-- Maven -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.9.1</version> <!-- 或者最新版本 -->
</dependency>
<!-- Gradle (如果使用Spring Boot Plugin) -->
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'io.jsonwebtoken:jjwt-api:0.9.1' // 或者最新版本
```
2. 配置JWT处理器:在`application.yml`或`application.properties`文件中配置JWT处理器,例如:
```yaml
# application.yml
security:
oauth2:
client:
registration:
jwt:
client-id: jwt-client
secret: your-secret-key
scope: read write
tokenUri: /token
spring:
cloud:
gateway:
routes:
- id: jwt-route
uri: lb://backend
predicates:
- Path=/api/** # 匹配所有/api路径下的请求
filters:
- AuthorizationTokenResolver
```
这里的`client-id`、`secret-key`和`tokenUri`需要替换为实际的客户端ID、密钥和令牌生成端点。
3. 实现AuthorizationTokenResolver过滤器:创建一个实现`WebFilter`接口的类,比如`JwtAuthorizationFilter`,解析HTTP头中的JWT:
```java
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.server.WebFilterExchange;
import io.jsonwebtoken.Claims;
public class JwtAuthorizationFilter implements WebFilter {
private final AuthenticationManager authenticationManager;
public JwtAuthorizationFilter(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
@Override
public Mono<Void> filter(ServerHttpRequest request, WebFilterExchange exchange) throws Exception {
String authorizationHeader = request.getHeaders().getFirst("Authorization");
if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
String jwt = authorizationHeader.substring("Bearer ".length());
try {
Claims claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(jwt).getBody();
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(claims.getSubject(), null, claims.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authenticationManager.authenticate(usernamePasswordAuthenticationToken));
} catch (Exception e) {
// 处理JWT验证失败的情况
log.error("Invalid JWT", e);
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
}
}
return exchange.getChain().filter(request);
}
}
```
4. 自定义SecurityConfiguration:确保`SecurityWebAutoConfiguration`被禁用,然后自定义一个`SecurityConfiguration`类以注入刚刚创建的`JwtAuthorizationFilter`:
```java
@Configuration
@EnableWebSecurity
public class CustomSecurityConfig extends WebSecurityConfigurerAdapter {
private final JwtAuthorizationFilter jwtAuthorizationFilter;
public CustomSecurityConfig(JwtAuthorizationFilter jwtAuthorizationFilter) {
this.jwtAuthorizationFilter = jwtAuthorizationFilter;
}
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) throws Exception {
http.oauth2Login()
.jwt().jwtAuthorizationRequestConverter(new JwtAuthorizationRequestConverter())
.and()
.addFilterAfter(jwtAuthorizationFilter, UsernamePasswordAuthenticationFilter.class);
// 其他安全设置...
return http.build();
}
}
```
5. 启动应用:运行你的应用程序,现在JWT认证已经启用,对匹配`/api/**`路由的所有API请求,Spring Cloud Gateway会在接收到请求时检查JWT。
阅读全文