HMAC Calculation
The HMAC value is obtained through salted hash calculation. The salt value (salt/secret) is generated by the third party itself.
You can generate it using the following command: openssl rand -base64 64
After generation, it needs to be saved on the business system server, and configured on the Document Platform server at the same time. The salt value needs to be carefully kept to prevent exposure.
HMAC Calculation Steps:
- Concatenate the URL. The URL does not include the request protocol, request host information, and the request parameter HMAC
- The third-party service calls the third-party server to generate the HMAC value
- Append the request parameter HMAC to the end of the URL
- Open the URL in an iframe or new tab
New Tab Opens Editing Page Example
Frontend Code
const userinfo = {
id: 'test-1',
display_name: 'test-1',
email: 'test-1@zOffice.com'
}
const userinfoStr = btoa(JSON.stringify(userinfo));
const path = `/docs/app/driver-callback?repo=thirdparty&docId=kyKtKHsbShsK&action=edit&userinfo=${userinfoStr}`;
const host = 'http://zOfficeServer:8001';
// Call third-party API to get HMAC value
const pathWithHmac = axios.get(`http://3rd-party/getPathWithHmac?path=${path}`);
window.open(`${host}${pathWithHmac}`);
Backend Code
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.math.BigInteger;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
@RestController
@Slf4j
public class HmacController {
@GetMapping("/getPathWithHmac")
@ResponseBody
public static String getHmac(String path) throws NoSuchAlgorithmException, InvalidKeyException, URISyntaxException {
StringBuilder builder = new StringBuilder(path);
builder.append("&ts=").append(new Date().getTime());
String secret = "xxxxxxxx"; // Document Platform frontend integration secret key, please do not use on the frontend to avoid leakage
SecretKeySpec hmacSHA256 = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(hmacSHA256);
URI uri = new URI(builder.toString());
String reqUrl = uri.getRawPath() + "?" + uri.getRawQuery();
mac.update(reqUrl.getBytes(StandardCharsets.UTF_8));
String hmac = String.format("%064x", new BigInteger(1, mac.doFinal()));
builder.append("&HMAC=").append(hmac);
return builder.toString();
}}