0

我已经访问并阅读了所有的 Valence,特别是 REST API 页面。我已经有一个已批准的密钥和另一个尚未获得 D2L 批准的密钥,目前尚不清楚我如何请求该批准。

该文档包含大量信息,但很难将所有部分放在一起。例如,为了进行任何 REST API 调用,我必须在调用的末尾添加几个参数。参数记录在一个地方,但在某些情况下不清楚如何构造它们(例如,关键之一是包含 url、时间戳和正在进行的调用的类型,但它们如何被连接起来?)。然后必须对它们进行签名,并且说明如何对密钥进行签名的文档位于完全不同的页面中,该页面甚至没有从告诉您必须对参数进行签名的页面中引用。最重要的是,文档对于如何进行签名并不是非常清楚,也没有提供进一步的解释或示例。所以去任何地方,我们必须在文档中跳来跳去,并经历大量的试验和错误。该文档似乎假设读者在多个领域具有专业知识,这可能是真的,也可能不是。

代码示例将产生巨大的影响。

4

1 回答 1

1

目前还没有很多样品;我们正在努力添加更多内容,并使现有的内容更加明显。作为一个例子,有一个Java Android 应用程序具有所有身份验证内容和一些基本调用(包括调用“whoami”,这是一个很好的测试调用)。

特定的身份验证相关文件也可用。从D2LSigner类中,您可以看到我们使用的签名算法:

Mac hmacSha256 = Mac.getInstance("hmacSHA256");
byte[] keyBytes = key.getBytes("UTF-8");                 
Key k = new SecretKeySpec(keyBytes, "hmacSHA256");

hmacSha256.init(k);

byte[] dataBytes = data.getBytes("UTF-8");
byte[] sig = hmacSha256.doFinal(dataBytes)

String sigString = base64Url( sig );

D2LOperationSecurityImpl,您可以看到查询字符串如何组合在一起:

//uppercase METHOD, lowercase PATH, timestamp as string 
private static /*final*/ String BASE_STRING_TEMPLATE = "{0}&{1}&{2}"; 

private static /*final*/ String APP_ID_QUERY_NAME = "x_a";
private static /*final*/ String APP_SIG_QUERY_NAME = "x_c";
private static /*final*/ String USER_ID_QUERY_NAME = "x_b";
private static /*final*/ String USER_SIG_QUERY_NAME = "x_d";
private static /*final*/ String TIMESTAMP_QUERY_NAME = "x_t";

...

@Override
public Uri createAuthenticatedUri(String path, String httpMethod) {

    long timestamp = System.currentTimeMillis() +
                     mServerSkewCorrectionMillis.longValue();

    Long timestampObjectSeconds = new Long(timestamp/1000);
    Object[]formatParms = {httpMethod.toUpperCase(),
                           path.toLowerCase(),
                           timestampObjectSeconds.toString()};

    String signatureBaseString = MessageFormat.format(BASE_STRING_TEMPLATE,
                                                      formatParms); 

    String appSig = D2LSigner.base64URLSig(mAppKey, signatureBaseString);
    String userSig = D2LSigner.base64URLSig(mUserKey, signatureBaseString);

    if ((appSig == null) || (userSig == null)) {
        return null;
    }

    String scheme = mEncryptOperations?ENCRYPED_SCHEME:PLAIN_SCHEME;
    Uri.Builder b  = new Uri.Builder();

    b.scheme(scheme);
    b.authority(mHostName);
    b.path(path);
    b.appendQueryParameter(APP_ID_QUERY_NAME, mAppID);
    b.appendQueryParameter(APP_SIG_QUERY_NAME, appSig);
    b.appendQueryParameter(USER_ID_QUERY_NAME, mUserID);
    b.appendQueryParameter(USER_SIG_QUERY_NAME, userSig);
    b.appendQueryParameter(TIMESTAMP_QUERY_NAME, timestampObjectSeconds.toString());

    Uri securedURI = b.build();

    return securedURI;
}

此外,您需要对用于登录的第一个 URL 进行签名,但只能使用应用程序密钥(因为您尚未建立用户上下文)。它使用不同的基本字符串(以保护在身份验证期间使用的 URL):

String signature = D2LSigner.base64URLSig(mAppKey, resultURLString);
BasicNameValuePair appID = new BasicNameValuePair(APP_ID_NAME, mAppID);
BasicNameValuePair appSig = new BasicNameValuePair(APP_SIG_NAME, signature);
BasicNameValuePair callbackURL = new BasicNameValuePair(CALLBACK_NAME, resultURLString);
于 2012-01-23T19:12:25.930 回答