SpringCloud Gateway 權限認證的實現(xiàn)
在微服務架構中,Spring Cloud Gateway 作為網(wǎng)關層,承擔著請求轉發(fā)、權限校驗等重要職責。通過集成 Spring Security 和 JWT(JSON Web Token),可以在網(wǎng)關層實現(xiàn)集中式的權限認證,確保系統(tǒng)的安全性和數(shù)據(jù)保護。以下是詳細的實現(xiàn)步驟:
一、添加依賴
在 Spring Boot 項目中,添加 Spring Cloud Gateway、Spring Security 和 JWT 相關依賴。以下是 pom.xml
的配置示例:
<dependencies> <!-- Spring Cloud Gateway --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <!-- Spring Security --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <!-- JWT Support --> <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> <scope>runtime</scope> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-jackson</artifactId> <version>0.11.5</version> <scope>runtime</scope> </dependency> </dependencies>
二、配置 Spring Security
在 Spring Cloud Gateway 中,使用 Spring Security 的 WebFlux 模塊來實現(xiàn)權限校驗。以下是一個典型的配置類:
@Configuration @EnableWebFluxSecurity public class SecurityConfig { @Bean public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http, JwtAuthenticationManager jwtAuthenticationManager) { http .csrf().disable() // 禁用 CSRF 保護 .authorizeExchange(exchanges -> exchanges .pathMatchers("/login", "/register").permitAll() // 公開登錄和注冊接口 .anyExchange().authenticated()) // 其他請求需要認證 .addFilterAt(jwtAuthenticationFilter(jwtAuthenticationManager), SecurityWebFilterChain.class); return http.build(); } private AuthenticationWebFilter jwtAuthenticationFilter(JwtAuthenticationManager jwtAuthenticationManager) { AuthenticationWebFilter filter = new AuthenticationWebFilter(jwtAuthenticationManager); filter.setServerAuthenticationConverter(new BearerTokenServerAuthenticationConverter()); return filter; } }
三、實現(xiàn) JWT 工具類
JWT 工具類用于生成和解析 JWT 令牌。以下是工具類的實現(xiàn):
@Component public class JwtUtil { private String secret = "yourSecretKey"; // 密鑰應存儲在安全的地方,避免硬編碼 public Mono<String> extractUsername(String token) { return Mono.just(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).parseClaimsJws(token).getBody(); } public Mono<String> generateToken(UserDetails userDetails) { Map<String, Object> claims = new HashMap<>(); return Mono.just(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() + 1000 * 60 * 60 * 10)) // 10小時過期 .signWith(SignatureAlgorithm.HS256, secret) .compact(); } public Mono<Boolean> validateToken(String token, UserDetails userDetails) { final String username = extractUsername(token).block(); return Mono.just(username.equals(userDetails.getUsername()) && !isTokenExpired(token)); } private Boolean isTokenExpired(String token) { return extractExpiration(token).before(new Date()); } }
四、實現(xiàn) JWT 認證管理器
JWT 認證管理器用于處理 JWT 的驗證邏輯:
@Component public class JwtAuthenticationManager implements ReactiveAuthenticationManager { private final JwtUtil jwtUtil; private final UserDetailsService userDetailsService; public JwtAuthenticationManager(JwtUtil jwtUtil, UserDetailsService userDetailsService) { this.jwtUtil = jwtUtil; this.userDetailsService = userDetailsService; } @Override public Mono<Authentication> authenticate(Authentication authentication) { String token = (String) authentication.getCredentials(); return jwtUtil.extractUsername(token) .flatMap(username -> { if (jwtUtil.validateToken(token, userDetailsService.loadUserByUsername(username)).block()) { UserDetails userDetails = userDetailsService.loadUserByUsername(username); return Mono.just(new UsernamePasswordAuthenticationToken(userDetails, token, userDetails.getAuthorities())); } else { return Mono.empty(); } }); } }
五、實現(xiàn) Bearer Token 轉換器
Bearer Token 轉換器用于從請求頭中提取 JWT 令牌:
public class BearerTokenServerAuthenticationConverter implements ServerAuthenticationConverter { @Override public Mono<Authentication> convert(ServerWebExchange exchange) { String authHeader = exchange.getRequest().getHeaders().getFirst("Authorization"); if (authHeader != null && authHeader.startsWith("Bearer ")) { String token = authHeader.substring(7); return Mono.just(new BearerTokenAuthentication(token)); } return Mono.empty(); } }
六、配置 Gateway 路由
在 application.yml
文件中配置路由規(guī)則:
spring: cloud: gateway: routes: - id: user-service uri: lb://USER-SERVICE predicates: - Path=/users/** filters: - JwtAuthenticationFilter
七、總結
到此這篇關于SpringCloud Gateway 權限認證的實現(xiàn)的文章就介紹到這了,更多相關SpringCloud Gateway 權限認證內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
- springcloud-gateway整合jwt+jcasbin實現(xiàn)權限控制的詳細過程
- SpringCloud Gateway中斷言路由和過濾器的使用詳解
- SpringCloud的網(wǎng)關Zuul和Gateway詳解
- SpringCloudGateway 網(wǎng)關登錄校驗實現(xiàn)思路
- springcloud gateway如何配置動態(tài)路由
- SpringCloudGateway路由失效問題
- SpringCloud Gateway路由核心原理解析
- SpringCloud-Gateway網(wǎng)關的使用實例教程
- 使用SpringCloud Gateway解決跨域問題
- springcloud?gateway實現(xiàn)簡易版灰度路由步驟詳解
相關文章
Java生成10個1000以內的隨機數(shù)并用消息框顯示數(shù)組內容然后求和輸出
這篇文章主要介紹了Java生成10個1000以內的隨機數(shù)并用消息框顯示數(shù)組內容然后求和輸出,需要的朋友可以參考下2015-10-10java.lang.ClassCastException的問題解決
本文主要介紹了java.lang.ClassCastException的問題解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2024-06-06