您好,登錄后才能下訂單哦!
1.Spring Cloud Gateway簡介
Spring Cloud Gateway是Spring Cloud官方推出的第二代網關框架,取代Zuul網關。網關作為流量的,在微服務系統中有著非常作用,網關常見的功能有路由轉發、權限校驗、限流控制等作用。
2.創建工程
本文我們采用最新的Spring Cloud 版本“Finchley.SR2”,注意該版本對應Spring Boot為2x。官方推薦的是:2.0.6.RELEASE版本。
父項目導入如下包:
org.springframework.boot
spring-boot-starter-parent
2.0.8.RELEASE
pom
import
org.springframework.cloud
spring-cloud-dependencies
Finchley.SR2
pom
import
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.3.0
com.alibaba
dubbo
2.6.6
com.alibaba.spring
spring-context-support
1.0.2
org.apache.curator
curator-framework
4.0.1
org.apache.zookeeper
zookeeper
3.4.6
org.hibernate
hibernate-validator
6.0.9.Final
gateway網關服務導入如下jar:
org.springframework.cloud
spring-cloud-starter-gateway
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-starter-aop
com.alibaba
dubbo
com.alibaba.spring
spring-context-support
org.apache.curator
curator-framework
org.apache.zookeeper
zookeeper
org.slf4j
slf4j-log4j12
log4j
log4j
com.uaf.credit
uaf-credit-api
org.springframework.boot
spring-boot-starter-web
父項目統一管理jar包的版本,子項目就不必再添加jar對應的版本號
網關服務的yml配置如下:
server:
port: 8817
spring:
application:
name: uaf-credit-gateway
security:
user:
name: wxt
password: wxt2016
cloud:
gateway:
routes:
- id: credit-auth-route
uri: http://10.168.xx.xx:8820/credit-auth/v1
predicates:
- Path=/credit-auth/v1/* #路徑匹配,匹配所有請求路徑以/credit-auth開頭的用戶請求
logging:
config: classpath:logback.xml
3.Spring Cloud Gateway過濾器
Spring-Cloud-Gateway的filter包中吉接口有如下三個,GatewayFilter,GlobalFilter,GatewayFilterChain,GlobalGilter 全局過濾器接口與 GatewayFilter 網關過濾器接口具有相同的方法定義。全局過濾器是一系列特殊的過濾器,會根據條件應用到所有路由中。網關過濾器是更細粒度的過濾器,作用于指定的路由中。
我們可以配置多個GlobalFilter過濾器,通過指定getOrder()方法的優先級來配置過濾器的執行順序。
@Component
public class RequestAuthFilter implements GlobalFilter, Ordered {
/**
* 請求方式驗證過濾器
* @param exchange
* @param chain
* @return reactor.core.publisher.Mono
* 作者:will
* 日期:2019/4/4 14:46
*/
@Override
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest serverHttpRequest = exchange.getRequest();
String method = serverHttpRequest.getMethodValue();
if(!"POST".equals(method)){
ServerHttpResponse response = exchange.getResponse();
String message= new ResponseUtils().CreditRespMsg(CreditException.ERR_100008,"非法請求",null);
byte[] bits = message.getBytes(StandardCharsets.UTF_8);
DataBuffer buffer = response.bufferFactory().wrap(bits);
response.setStatusCode(HttpStatus.UNAUTHORIZED);
//指定編碼,否則在瀏覽器中會中文亂碼
response.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");
return response.writeWith(Mono.just(buffer));
}
return chain.filter(exchange);
}
/**
* 優先級
* @return int 數字越大優先級越低
* 作者:will
* 日期:2019/4/4 13:36
*/
@Override
public int getOrder() {
return 0;
}
}
4.Spring boot Security認證
Spring Security致力于為Java應用提供認證和授權管理。它是一個強大的,高度自定義的認證和訪問控制框架,這句話包括兩個關鍵詞:Authentication(認證)和 Authorization(授權,也叫訪問控制)。
需要安全認證的服務需要導入如下Jar:
org.springframework.boot
spring-boot-starter-security
yml配置:
server:
port: 8820
servlet:
context-path: /credit-auth
spring:
application:
name: uaf-credit-auth
security:
user:
name: wxt
password: wxt2016
roles:
- USER
logging:
config: classpath:logback.xml
接下來配置認證類:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
/**表示所有的訪問都必須進行認證處理后才可以正常進行*/
http.httpBasic().and().authorizeRequests().anyRequest().fullyAuthenticated();
/**所有的Rest服務一定要設置為無狀態,以提升操作性能*/
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
/**關閉csrf避免POST請求時出現401異常*/
http.csrf().disable();
http.authorizeRequests().antMatchers(org.springframework.http.HttpMethod.GET).permitAll();
}
}
這里有個問題,外面的服務若請求我們的服務需要進行Security認證,但我們的網關應該需要免認證。
我們通過Gateway的GlobalFilter過濾器的方式實現:
@Component
public class OAuthSignatureFilter implements GlobalFilter, Ordered {
/**授權訪問用戶名*/
@Value("${spring.security.user.name}")
private String securityUserName;
/**授權訪問密碼*/
@Value("${spring.security.user.password}")
private String securityUserPassword;
/**
* OAuth過濾器
* @param exchange
* @param chain
* @return reactor.core.publisher.Mono
* 作者:will
* 日期:2019/4/4 13:36
*/
@Override
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
/**oauth授權*/
String auth= securityUserName.concat(":").concat(securityUserPassword);
String encodedAuth = new sun.misc.BASE64Encoder().encode(auth.getBytes(Charset.forName("US-ASCII")));
//注意Basic后面有空格
String authHeader= "Basic " +encodedAuth;
//向headers中放授權信息
ServerHttpRequest serverHttpRequest = exchange.getRequest().mutate().header("Authorization",authHeader).build();
//將現在的request變成change對象
ServerWebExchange build =exchange.mutate().request(serverHttpRequest).build();
return chain.filter(build);
}
/**
* 優先級
* @return int 數字越大優先級越低
* 作者:will
* 日期:2019/4/4 13:36
*/
@Override
public int getOrder() {
return 2;
}
5.新增自定義過濾器
gateway里面可以自定義普通filter,也可以創建自定義的GlobalFilter,我們通過繼承AbstractGatewayFilterFactory實現自定義過濾器。
yml新增如下配置:
spring:
application:
name: uaf-credit-gateway
security:
user:
name: wxt
password: wxt2016
cloud:
gateway:
routes:
- id: credit-auth-route
uri: http://10.168.xx.xx:8820/credit-auth/v1
predicates:
- Path=/credit-auth/v1/* #路徑匹配,匹配所有請求路徑以/credit-auth開頭的用戶請求
filters:無錫人流醫院 http://xmobile.wxbhnk120.com/
- CreditFilter #注意與定義的過濾器類名一致
新增CreditFilter.java類,自定義過濾器的優先級低于GlobalFilter
@Configuration
public class CreditFilter extends AbstractGatewayFilterFactory {
public CreditFilter() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
MySlf4j.textInfo("進入自定義Credit過濾器");
return (exchange, chain) -> {
String jwtToken = exchange.getRequest().getHeaders().getFirst("Authorization");
//校驗jwtToken的合法性
if (jwtToken != null) {
// 合法
// 將用戶id作為參數傳遞下去
return chain.filter(exchange);
}
//不合法(響應未登錄的異常)
ServerHttpResponse response = exchange.getResponse();
//設置headers
HttpHeaders httpHeaders = response.getHeaders();
httpHeaders.add("Content-Type", "application/json; charset=UTF-8");
httpHeaders.add("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0");
//設置body
String warningStr = "未登錄或登錄超時";
DataBuffer bodyDataBuffer = response.bufferFactory().wrap(warningStr.getBytes());
return response.writeWith(Mono.just(bodyDataBuffer));
};
}
public static class Config {
}
@Bean
public CreditFilter creditFileterFactory() {
return new CreditFilter();
}
}
至此我們的Gateway及相關的授權認證配置完成。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。