SpringCloud Gateway 權(quán)限認(rèn)證的實(shí)現(xiàn)
在微服務(wù)架構(gòu)中,Spring Cloud Gateway 作為網(wǎng)關(guān)層,承擔(dān)著請求轉(zhuǎn)發(fā)、權(quán)限校驗(yàn)等重要職責(zé)。通過集成 Spring Security 和 JWT(JSON Web Token),可以在網(wǎng)關(guān)層實(shí)現(xiàn)集中式的權(quán)限認(rèn)證,確保系統(tǒng)的安全性和數(shù)據(jù)保護(hù)。以下是詳細(xì)的實(shí)現(xiàn)步驟:
一、添加依賴
在 Spring Boot 項(xiàng)目中,添加 Spring Cloud Gateway、Spring Security 和 JWT 相關(guān)依賴。以下是 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 模塊來實(shí)現(xiàn)權(quán)限校驗(yàn)。以下是一個(gè)典型的配置類:
@Configuration @EnableWebFluxSecurity public class SecurityConfig { @Bean public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http, JwtAuthenticationManager jwtAuthenticationManager) { http .csrf().disable() // 禁用 CSRF 保護(hù) .authorizeExchange(exchanges -> exchanges .pathMatchers("/login", "/register").permitAll() // 公開登錄和注冊接口 .anyExchange().authenticated()) // 其他請求需要認(rèn)證 .addFilterAt(jwtAuthenticationFilter(jwtAuthenticationManager), SecurityWebFilterChain.class); return http.build(); } private AuthenticationWebFilter jwtAuthenticationFilter(JwtAuthenticationManager jwtAuthenticationManager) { AuthenticationWebFilter filter = new AuthenticationWebFilter(jwtAuthenticationManager); filter.setServerAuthenticationConverter(new BearerTokenServerAuthenticationConverter()); return filter; } }
三、實(shí)現(xiàn) JWT 工具類
JWT 工具類用于生成和解析 JWT 令牌。以下是工具類的實(shí)現(xiàn):
@Component public class JwtUtil { private String secret = "yourSecretKey"; // 密鑰應(yīng)存儲在安全的地方,避免硬編碼 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小時(shí)過期 .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()); } }
四、實(shí)現(xiàn) JWT 認(rèn)證管理器
JWT 認(rèn)證管理器用于處理 JWT 的驗(yàn)證邏輯:
@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(); } }); } }
五、實(shí)現(xiàn) Bearer Token 轉(zhuǎn)換器
Bearer Token 轉(zhuǎn)換器用于從請求頭中提取 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
七、總結(jié)
到此這篇關(guān)于SpringCloud Gateway 權(quán)限認(rèn)證的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)SpringCloud Gateway 權(quán)限認(rèn)證內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- springcloud-gateway整合jwt+jcasbin實(shí)現(xiàn)權(quán)限控制的詳細(xì)過程
- SpringCloud Gateway中斷言路由和過濾器的使用詳解
- SpringCloud的網(wǎng)關(guān)Zuul和Gateway詳解
- SpringCloudGateway 網(wǎng)關(guān)登錄校驗(yàn)實(shí)現(xiàn)思路
- springcloud gateway如何配置動態(tài)路由
- SpringCloudGateway路由失效問題
- SpringCloud Gateway路由核心原理解析
- SpringCloud-Gateway網(wǎng)關(guān)的使用實(shí)例教程
- 使用SpringCloud Gateway解決跨域問題
- springcloud?gateway實(shí)現(xiàn)簡易版灰度路由步驟詳解
相關(guān)文章
java 設(shè)計(jì)模式(DAO)的實(shí)例詳解
這篇文章主要介紹了java 設(shè)計(jì)模式(DAO)的實(shí)例詳解的相關(guān)資料,希望通過本文能幫助到大家,需要的朋友可以參考下2017-09-09java基礎(chǔ)--自己動手實(shí)現(xiàn)一個(gè)LRU
這篇文章主要介紹了運(yùn)用方案如何實(shí)現(xiàn)LUR,文章中通過代碼講解的非常詳細(xì),對大家的工作或?qū)W習(xí)有一定的參考價(jià)值,感興趣的朋友可以參考一下2021-08-08idea2023遠(yuǎn)程調(diào)試springboot的過程詳解
這篇文章主要介紹了idea2023遠(yuǎn)程調(diào)試,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-08-08Java生成10個(gè)1000以內(nèi)的隨機(jī)數(shù)并用消息框顯示數(shù)組內(nèi)容然后求和輸出
這篇文章主要介紹了Java生成10個(gè)1000以內(nèi)的隨機(jī)數(shù)并用消息框顯示數(shù)組內(nèi)容然后求和輸出,需要的朋友可以參考下2015-10-10java.lang.ClassCastException的問題解決
本文主要介紹了java.lang.ClassCastException的問題解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-06-06