B端系統的訪問通常須要進行權限認證,而且只對指定的IP開放。Fizz原生支持認證方式:MD5簽名、密鑰認證,支持IP白名單,而且支持經過自定義插件方式定製簽名和驗籤方法。本篇文章介紹Fizz網關中與B端系統接入相關的功能,而且經過一步步操做演示接入一個測試的B端系統。後端
appID管理功能用於配置應用認證信息,可配置是否啓用認證、是否啓用IP白名單,AppID級別的自定義配置供自定義插件使用。api
新增appID配置(網關管理 -> appID管理 -> 新增),以下圖所示:安全
點擊是否啓用認證
選項後開啓認證,以下圖所示:服務器
開啓認證後可選擇認證方式
,支持:markdown
MD5簽名:調用方需傳簽名請求頭fizz-sign和時間戳請求頭fizz-ts,生成MD5簽名: MD5(appid++時間戳++密鑰)app
密鑰認證:調用方需傳簽名請求頭fizz-sign, 值爲密鑰ide
自定義認證插件:自定義插件方式可定製簽名和驗籤方法測試
這裏咱們選擇MD5簽名
認證方式,並隨機生成密鑰
(faa780aaa80c46d68217ba0c3c25736d),以下圖所示:ui
點擊是否啓用IP白名單
選項後開啓IP白名單,以下圖所示:spa
這裏咱們開啓了IP白名單,而且將我開發機器的IP地址加入白名單。
最後保存,完成appID配置。
Fizz網關支持自定義認證插件,經過自定義認證插件可定製簽名和驗籤方法。
appID配置可添加自定義配置
內容,在自定義認證插件實現內可獲取到對應的配置,以下圖所示:
在fizz-gateway-community
項目中添加實現we.plugin.auth.CustomAuth
接口的實現類,代碼邏輯以下:
@Component(BusinessSignAuthPluginFilter.BUSINESS_SING_AUTH_PLUGIN_FILTER)
public class BusinessSignAuthPluginFilter implements CustomAuth {
private static final Logger log = LoggerFactory.getLogger(BusinessSignAuthPluginFilter.class);
public static final String BUSINESS_SING_AUTH_PLUGIN_FILTER = "businessSignAuthPlugin";
@Override
public Mono<ApiConfigService.Access> auth(ServerWebExchange exchange, String appId, String ip, String timestamp, String sign, App fizzAppConfig) {
ServerHttpRequest clientReq = exchange.getRequest();
HttpHeaders hdrs = clientReq.getHeaders();
if(StringUtils.isBlank(appId)){
//兼容
String businessAppId = hdrs.getFirst("app-id");
appId = businessAppId;
}
String customTimestamp=hdrs.getFirst("timestamp");
String customSign=hdrs.getFirst("sign");
String customSecretKey=fizzAppConfig.secretkey;
//是否開啓簽名
boolean useAuth=fizzAppConfig.useAuth;
try {
if (!StringUtils.isBlank(customTimestamp)) {
long times = Long.valueOf(customTimestamp);
if (System.currentTimeMillis() - times > 600000) {
return Mono.just(ApiConfigService.Access.CUSTOM_AUTH_REJECT);
}
}
}catch (Throwable e) {
log.error("timestamp error,appId:{},timestamp:{},sign:{}", appId, timestamp, customSign);
return Mono.just(ApiConfigService.Access.CUSTOM_AUTH_REJECT);
}
String sign2;
try {
sign2 = DigestUtils.sha256Hex((appId + "-" + customTimestamp + '-' + customSecretKey).getBytes(Charset.forName("UTF-8")));
} catch (Throwable e) {
log.error("sign error,appId:{},timestamp:{},sign:{}", appId, timestamp, customSign);
return Mono.just(ApiConfigService.Access.CUSTOM_AUTH_REJECT);
}
boolean checkSign = sign2.equalsIgnoreCase(customSign);
if (!checkSign && useAuth) {
log.error("sign error,appId:{},timestamp:{},sign:{},trueSign:{}", appId, timestamp, customSign, sign2);
return Mono.just(ApiConfigService.Access.CUSTOM_AUTH_REJECT);
}
// 獲取自定義配置
String selfConfig = fizzAppConfig.config;
if(!StringUtils.isBlank(selfConfig)){
// 使用自定義配置作一些處理
// Map<String,String> sconfig = JSON.parseObject(selfConfig, Map.class);
// enterpriseMebId = sconfig.get(NeedLogin.ENTERPRISE_MEB_ID);
// WebUtils.appendHeader(exchange,NeedLogin.ENTERPRISE_MEB_ID, enterpriseMebId);
}
return Mono.just(ApiConfigService.Access.YES);
}
}
複製代碼
完成後便可在appID配置中選擇自定義認證插件
認證方式來啓用定製的簽名和驗籤方法。
更多自定義認證插件介紹請查看Fizz網關插件、Fizz網關二次開發等相關文章。
配置服務或API路由規則,支持服務編排、服務發現、反向代理三種路由類型,支持插件配置。
新增路由配置(網關管理 -> 路由管理 -> 新增),以下圖所示:
路由配置支持如下路由類型:
服務編排
功能模塊下維護,詳情查看服務編排相關文章)服務發現
的服務名這裏我本地起了一個名爲b-service
的測試服務,啓動端口爲8080
,上下文爲/b-service
,提供對外的接口爲/b-interface
。所以路由配置選用反向代理
選項,而且啓用調用方(appID)
選項開啓認證,最終配置以下圖所示:
測試服務b-service
配置文件application.yml
以下所示:
server:
port: 8080
servlet:
context-path: /b-service
複製代碼
接口/b-interface
實現以下所示:
@SpringBootApplication
@RestController
public class BServiceApplication {
public static void main(String[] args) {
SpringApplication.run(BServiceApplication.class, args);
}
@RequestMapping("/b-interface")
public Result bInterface() {
return Result.builder().code(200).msg("SUCCESS").build();
}
@Builder
@Data
public static class Result {
private final Integer code;
private final String msg;
}
}
複製代碼
啓動測試服務b-service
後經過Postman調用網關接口(個人fizz-gateway-community
服務的地址爲http://172.25.63.248:8600
),接口正常返回,以下圖所示:
其中使用Postman的預處理腳本設置請求頭以經過Fizz網關的認證,預處理腳本以下:
var CryptoJS = require('crypto-js')
var appId = pm.request.headers.get("fizz-appid");
var key = pm.request.headers.get("key");
var timestamp = Date.now();
pm.environment.set("fizz-ts", timestamp);
var sign = CryptoJS.MD5(appId + '_' + timestamp + '_' + key).toString()
pm.environment.set("fizz-sign", sign);
複製代碼
請求頭配置以下:
fizz-appid:test-b-service
key:faa780aaa80c46d68217ba0c3c25736d
fizz-ts:{{fizz-ts}}
fizz-sign:{{fizz-sign}}
複製代碼
至此,咱們的測試服務b-service
成功接入Fizz網關,外部請求設置正確的請求頭信息經過Fizz的認證,最後正常訪問到/b-interface
接口。
B端系統接入Fizz網關主要使用到了Fizz網關的appID管理
、路由管理
功能,經過Fizz網關的權限認證、IP白名單過濾以及動態路由能力將B端系統服務安全的暴露給第三方對接企業使用。