For the sake of security, the interface of external services often needs to perform corresponding security processing: data encryption transmission and identity authentication. There are two types of data encryption transmission: symmetric encryption and asymmetric encryption. For the sake of more security, it is better to use asymmetric encryption, and digital signature can be used for identity authentication. The purpose of developing this sdk is to quickly realize the safe opening of the api in the project.
spring-boot
cn.hutool.hutool-all
- Responsible for opening the interface to the outside world (Provide services based on HTTP)
- Implement the encryption and decryption of interface parameters and return values (use asymmetric encryption: RSA/SM2, or symmetric encryption: AES/SM4)
- Implement the signature verification of the interface (The server will verify the client's signature to ensure that the caller's identity and data are not tampered with)
- Provide client sdk and server sdk to facilitate the rapid integration of open api functions in existing projects
- Implemented three API security interaction methods: only signing + asymmetric encryption + symmetric encryption, configuration switching can be performed
- Implemented a variety of encryption algorithms such as RSA and SM2 for encryption and decryption of interface parameters and return values
- A set of data transmission mechanism is specially customized for file transfer, making file transfer more convenient and fast
- Implemented the server interface document function, which is convenient for querying all API interfaces
- Method invocation implements HTTP timeout, HTTP proxy and other settings, and supports method-level configuration
<dependency>
<groupId>io.github.hdwang123</groupId>
<artifactId>openapi-server-sdk</artifactId>
<version>1.5.12</version>
</dependency>
@Component
public class OpenApiConfigImpl implements OpenApiConfig {
@Value("${keys.local.rsa.privateKey}")
private String privateKey;
@Value("${keys.remote.rsa.publicKey}")
private String callerPublicKey;
@Override
public AsymmetricCryEnum getAsymmetricCry() {
//设置非对称加密算法
return AsymmetricCryEnum.RSA;
}
@Override
public String getCallerPublicKey(String callerId) {
//TODO 根据调用者ID查找调用者的公钥(可以将所有调用者的公钥存到数据库中)
return callerPublicKey;
}
@Override
public String getSelfPrivateKey() {
//设置服务端私钥
return privateKey;
}
@Override
public boolean retEncrypt() {
//设置返回值是否需要加密
return true;
}
@Override
public CryModeEnum getCryMode() {
//设置加密模式
return CryModeEnum.SYMMETRIC_CRY;
}
@Override
public SymmetricCryEnum getSymmetricCry() {
//设置对称加密算法
return SymmetricCryEnum.AES;
}
@Override
public boolean enableDoc() {
//是否启用接口文档功能
return true;
}
}
@Slf4j
@OpenApi("userApi")
public class UserApi {
@OpenApiMethod("getUserById")
public User getUserById(Long id) {
log.info("getUserById:id=" + id);
User user = new User();
user.setId(1L);
user.setName("bob");
return user;
}
}
url:http://localhost:8080/openapi/doc.html
Replace http://localhost:8080 with the actual path in the actual project
<dependency>
<groupId>io.github.hdwang123</groupId>
<artifactId>openapi-client-sdk</artifactId>
<version>1.5.12</version>
</dependency>
Call OpenApiClient directly
@Slf4j
@Component
public class UserApiClient {
@Value("${keys.local.rsa.privateKey}")
private String privateKey;
@Value("${keys.remote.rsa.publicKey}")
private String remotePublicKey;
String baseUrl = "http://localhost:8080";
/**
* 定义OpenApiClient
*/
OpenApiClient apiClient = null;
@PostConstruct
public void init() {
apiClient = new OpenApiClientBuilder(baseUrl, privateKey, remotePublicKey, "001", "userApi")
.asymmetricCry(AsymmetricCryEnum.RSA)
.retDecrypt(true)
.cryModeEnum(CryModeEnum.SYMMETRIC_CRY)
.symmetricCry(SymmetricCryEnum.AES)
.build();
}
public void getUserById() {
OutParams outParams = apiClient.callOpenApi("getUserById", 10001);
log.info("返回值:" + outParams);
}
}
Use the annotation @OpenApiRef to define a service reference and inject it where needed
- Define the configuration
openapi:
client:
config:
openApiRefPath: openapi.example.client.openapiclient
baseUrl: http://localhost:8080
selfPrivateKey: ${keys.local.rsa.privateKey}
remotePublicKey: ${keys.remote.rsa.publicKey}
asymmetricCryEnum: RSA
retDecrypt: true
cryModeEnum: SYMMETRIC_CRY
symmetricCryEnum: AES
callerId: "001"
httpConnectionTimeout: 3
httpReadTimeout: 6
# httpProxyHost: 127.0.0.1
# httpProxyPort: 8888
- Define the service reference
@OpenApiRef(value = "userApi")
public interface UserApiClient {
@OpenApiMethod("getUserById")
User getUserById(Long id);
}
- Inject the service reference to call the remote openapi service
@Component
public class UserApiTest2 {
@Autowired
UserApiClient userApiClient;
public void getUserById() {
User user = userApiClient.getUserById(10001L);
log.info("ret:" + user);
}
}