# Preface

Access to B-side systems generally requires permission authentication and is only open to designated IPs. FizzGate natively supports authentication methods: MD5 signature, key authentication, supports IP whitelist, and supports customized signature and signature verification methods through custom plug-ins. This article introduces the functions related to B-side system access in the FizzGate integration platform, and demonstrates access to a test B-side system through step-by-step operations.

# appID management

The appID management function is used to configure application authentication information. You can configure whether to enable authentication and whether to enable IP whitelisting. Custom configuration at the AppID level is available for custom plug-ins.

# Enable authentication

Add new appID configuration (Gateway Management -> appID Management -> New), as shown in the following figure:

b_service_access_app_id_1

Click the Whether to enable authentication option to enable authentication, as shown in the figure below:

b_service_access_app_id_2

After turning on authentication, you can select authentication method, which supports:

  • MD5 signature: The caller needs to pass the signature request header fizz-sign and the timestamp request header fizz-ts to generate an MD5 signature: MD5(appid++timestamp++key)

b_service_access_app_id_3

  • Key authentication: The caller needs to pass the signature request header fizz-sign, and the value is the key

b_service_access_app_id_4

  • Custom authentication plug-in: The custom plug-in method can customize the signature and signature verification methods

b_service_access_app_id_5

Here we choose the MD5 signature authentication method and randomly generate the key (faa780aaa80c46d68217ba0c3c25736d), as shown in the figure below:

b_service_access_app_id_6

# Enable IP whitelist

Click the Whether to enable IP whitelist option to enable the IP whitelist, as shown in the figure below:

b_service_access_app_id_7

Here we turn on the IP whitelist and add the IP address of my development machine to the whitelist.

Finally save and complete the appID configuration.

# Custom authentication plug-in

The FizzGate integration platform supports custom authentication plug-ins, through which the signature and signature verification methods can be customized.

# Plug-in configuration

The appID configuration can add custom configuration content, and the corresponding configuration can be obtained in the custom authentication plug-in implementation, as shown in the following figure:

b_service_access_auth_plugin_1

# Plug-in logic implementation

Add an implementation class that implements the we.plugin.auth.CustomAuth interface in the fizz-gateway-node project. The code logic is as follows:

@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)){
//Compatible
String businessAppId = hdrs.getFirst("app-id");
appId = businessAppId;
}
String customTimestamp=hdrs.getFirst("timestamp");
String customSign=hdrs.getFirst("sign");
String customSecretKey=fizzAppConfig.secretkey;
//Whether to enable signature
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);
}

// Get custom configuration
String selfConfig = fizzAppConfig.config;
if(!StringUtils.isBlank(selfConfig)){
//Use custom configuration to do some processing
// 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);
}
}

After completion, you can select the custom authentication plug-in authentication method in the appID configuration to enable customized signature and signature verification methods.

For more introductions to custom authentication plug-ins, please see related articles such as FizzGate Integration Platform Plug-in, FizzGate Integration Platform Secondary Development, etc.

##Route management

Configure service or API routing rules, support three routing types: service orchestration, service discovery, and reverse proxy, and support plug-in configuration.

# Routing configuration

Add a new routing configuration (Gateway Management -> Routing Management -> New), as shown in the following figure:

b_service_access_api_auth_1

Route configuration supports the following route types:

  • Service orchestration, forward the request to the service orchestration interface (the service orchestration interface is maintained under the service orchestration function module, see service orchestration related articles for details)

b_service_access_api_auth_2

  • Service discovery, this method is used when the backend service and gateway are connected to the same registration center (supports Eureka, Nacos), the backend service name option lists all service names of service discovery

b_service_access_api_auth_3

  • Reverse proxy, forward the request to the backend server IP/domain name and port

b_service_access_api_auth_4

Here I have a local test service named b-service, the startup port is 8080, the context is /b-service, and the external interface provided is /b-interface. Therefore, the routing configuration uses the reverse proxy option, and the caller (appID) option is enabled to enable authentication. The final configuration is as shown below:

b_service_access_api_auth_5

# Initiate a request

The test service b-service configuration file application.yml is as follows:

server:
   port: 8080
   servlet:
     context-path: /b-service

The interface /b-interface is implemented as follows:

@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;
}
}

After starting the test service b-service, call the gateway interface through Postman (the address of my fizz-gateway-node service is http://172.25.63.248:8600), and the interface returns normally, as shown in the following figure:

b_service_access_request_1

Postman's preprocessing script is used to set the request header to pass the authentication of the FizzGate integration platform. The preprocessing script is as follows:

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);

The request header configuration is as follows:

fizz-appid:test-b-service
key:faa780aaa80c46d68217ba0c3c25736d
fizz-ts:{{fizz-ts}}
fizz-sign:{{fizz-sign}}

At this point, our test service b-service is successfully connected to the FizzGate integration platform, the external request sets the correct request header information and passes FizzGate authentication, and finally accesses the /b-interface interface normally.

# Summarize

The B-side system accesses the FizzGate integration platform and mainly uses the appID management and routing management functions of the FizzGate integration platform. The B-side system services are safely exposed through the authority authentication, IP whitelist filtering and dynamic routing capabilities of the FizzGate integration platform. For use by third-party docking companies.