公司让百度定制了一个产品,因为某些原因需要调用百度的接口。(这里本来可以用百度的SKD,大师因为是定制化的产品,接口也是高度定制化的,所以没法傻瓜式的操作使用SDK。需要自己生成签名)经过几日钻研之后,终于成功了。然后我把代码简单的封装了一下。
百度云鉴权认证机制
百度云签名算法实现
参考博客:菜鸟吉吉 -百度云API鉴权-java
先添加百度云的sdk
com.baidubce bce-java-sdk 0.10.181
因为需求中需要用临时凭证来生成签名算法,所以我封装了一个工具类来完成两种不同签名的算法(临时的和非临时的)。
生成临时凭证private static final String STS_ENDPOINT = "http://sts.bj.baidubce.com";
private static final String ENDPOINT = "bj.bcebos.com";
private static final String ACCESS_KEY_ID = "ac5d5e37ff554d24a216aa91eb7f5358";
private static final String SECRET_ACCESS_KEY = "07c72a187cfc42648a0f89d6cefff5f2";
public static void main(String[] args) {
BceCredentials credentials = new DefaultBceCredentials(ACCESS_KEY_ID, SECRET_ACCESS_KEY);
StsClient client = new StsClient(
new BceClientConfiguration().withEndpoint(STS_ENDPOINT).withCredentials(credentials));
GetSessionTokenResponse response = client.getSessionToken(new GetSessionTokenRequest());
//临时凭证的ak
String accessKeyId = response.getAccessKeyId();
//临时凭证的sk
String secretAccessKey = response.getSecretAccessKey();
//临时凭证的sessionToken
String sessionToken = response.getSessionToken();
}
签名生成工具类
public class AuthorizationStrUtils {
public static Map createAuthorization(String access_key_id, String secret_access_key, String url,
Map headers ,HttpMethodName httpMethodName,
Map parameters){
BceV1Signer v1Signer = new BceV1Signer();
try {
URI uri = new URI(url);
InternalRequest internalRequest = new InternalRequest(httpMethodName , uri);
//设置请求参数
if (parameters == null){
parameters = Maps.newHashMap();
}
internalRequest.setParameters(parameters);
//设置请求头时间 -此时间是格林威治时间 转成的百度云需要的格式
headers.put("x-bce-date",DateUtils.formatAlternateIso8601Date(new Date()));
internalRequest.setHeaders(headers);
//选择签名运算项,临时凭证需要多一个token来运算
SignOptions signOptions = new SignOptions();
if (headers.containsKey("x-bce-security-token")){
signOptions.setHeadersToSign(Sets.newHashSet("host","x-bce-date","x-bce-security-token"));
v1Signer.sign(internalRequest, new DefaultBceSessionCredentials(access_key_id, secret_access_key,headers.get("x-bce-security-token")),signOptions);
}else {
signOptions.setHeadersToSign(Sets.newHashSet("host","x-bce-date"));
v1Signer.sign(internalRequest, new DefaultBceCredentials(access_key_id, secret_access_key),signOptions);
}
String authorization = internalRequest.getHeaders().get("Authorization");
headers.put("Authorization",authorization);
} catch (URISyntaxException e) {
e.printStackTrace();
}
return headers;
}
}
调用工具类生成签名
//请求路径 String url = "http://bj.bcebos.com/v1/test"; //请求头在发起请求的时候可以复用 Mapheaders = Maps.newHashMap(); //host一般是固定的,具体参考官方文档 headers.put("Host","bj.bcebos.com"); //放入临时凭证的sessionToken ,不是临时的凭证就不需要放入了 headers.put("x-bce-security-token",sessionToken); AuthorizationStrUtils.createAuthorization(accessKeyId, secretAccessKey, url, headers, HttpMethodName.GET, null); //设置请求类型 headers.put("Content-Type","application/json; charset=utf-8"); //发起GET请求 这里用到了自己封装的http工具类,有兴趣的同学可以网上搜一搜 String result = HttpClientUtils.doGet("http://bj.bcebos.com/v1/test", headers, new HashMap<>()); System.out.println(result);
有了签名之后就可以用下面这个工具来验证我们的签名正确性了!不过注意需要把签名运算中唯一的变量 x-bce-date 给写死,不然每次生成的签名会不一样。
百度云在线签名计算工具
最后其实光看官方文档的介绍还是会走很多弯路的,所以算是把百度云的SDK二次封装分享给大家,让同学们少掉几根头发。



