IMS エミュレーター ( http://ltiapps.net/test/tc.php ) で [データを保存] をクリックすると、自動入力されたデータで outh_signature が生成され、フォーム frmLaunch(name='frmLaunch) の非表示の値として挿入されます。 ') 形。同様の outh_signature をプログラムで生成する必要がありますが、同じ oauth_nounce と oauth_timestamp を使用しているにもかかわらず、エミュレーターが生成している正確な oauth_signature を生成できません。生成中に送信する必要があるリクエスト本文が何であるかわかりませんサイン..
シナリオを再作成するには、以下の手順に従います
- URL http://ltiapps.net/test/tc.phpにアクセスします。
- [データをクリア] をクリックし、ポップアップで [OK] をクリックします
- ロールを学習者として選択し、[データを保存] をクリックします
データを保存すると、入力IDが「oauth_signature」のouth_signature隠し値が表示されます
以下の方法で生成しようとしましたが、期待される署名を取得できませんでした。
import java.io.*; import java.net.URL; import java.net.URLEncoder; import java.util.LinkedHashMap; import java.util.Map; import java.util.TreeMap; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import javax.net.ssl.HttpsURLConnection; // Apache Commons Libraries used for the Nonce & Base64 import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Hex; public class OAuthTest { public static void main(final String[] args) throws Exception { // Setup the variables necessary to create the OAuth 1.0 signature and make the request String httpMethod = "POST"; String consumerKey = "jisc.ac.uk"; String secret = "secret"; String signatureMethod = "HMAC-SHA1"; String body = ""; //mentioned in the description byte[] requestBody = null; URL url = new URL("http://ltiapps.net/test/tp.php"); // Set the Nonce and Timestamp parameters String nonce = "6d95eef168e568a530d1cd419a997952";//getNonce(); String timestamp = "1483470400";//getTimestamp(); System.out.println("Nonce:" + getNonce()); System.out.println("timestamp:" + getTimestamp()); // Set the request body if making a POST or PUT request if ("POST".equals(httpMethod) || "PUT".equals(httpMethod)) { requestBody = body.getBytes("UTF-8"); } // Create the OAuth parameter name/value pair Map<String, String> oauthParams = new LinkedHashMap<String, String>(); oauthParams.put("oauth_consumer_key", consumerKey); oauthParams.put("oauth_signature_method", signatureMethod); oauthParams.put("oauth_timestamp", timestamp); oauthParams.put("oauth_nonce", nonce); // Get the OAuth 1.0 Signature String signature = generateSignature(httpMethod, url, oauthParams, requestBody, secret); System.out.println(String.format("OAuth 1.0 Signature: %s", signature)); } private static String getNonce() { return RandomStringUtils.randomAlphanumeric(32); } private static String getTimestamp() { return Long.toString((System.currentTimeMillis() / 1000)); } private static String generateSignature( String httpMethod, URL url, Map<String, String> oauthParams, byte[] requestBody, String secret ) throws UnsupportedEncodingException { // Ensure the HTTP Method is upper-cased httpMethod = httpMethod.toUpperCase(); // Construct the URL-encoded OAuth parameter portion of the signature base string String encodedParams = normalizeParams(httpMethod, url, oauthParams, requestBody); // URL-encode the relative URL String encodedUri = URLEncoder.encode(url.getPath(), "UTF-8"); // Build the signature base string to be signed with the Consumer Secret String baseString = String.format("%s&%s&%s", httpMethod, encodedUri, encodedParams); return hmacSha1(baseString, secret); } private static String normalizeParams( String httpMethod, URL url, Map<String, String> oauthParams, byte[] requestBody ) throws UnsupportedEncodingException { // Sort the parameters in lexicographical order, 1st by Key then by Value Map<String, String> kvpParams = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER); kvpParams.putAll(oauthParams); // Place any query string parameters into a key value pair using equals ("=") to mark // the key/value relationship and join each parameter with an ampersand ("&") if (url.getQuery() != null) { for(String keyValue : url.getQuery().split("&")) { String[] p = keyValue.split("="); kvpParams.put(p[0],p[1]); } } // Include the body parameter if dealing with a POST or PUT request if ("POST".equals(httpMethod) || "PUT".equals(httpMethod)) { String body = Base64.encodeBase64String(requestBody).replaceAll("\r\n", ""); // url encode the body 2 times now before combining other params body = URLEncoder.encode(body, "UTF-8"); body = URLEncoder.encode(body, "UTF-8"); kvpParams.put("body", body); } // separate the key and values with a "=" // separate the kvp with a "&" StringBuilder combinedParams = new StringBuilder(); String delimiter=""; for(String key : kvpParams.keySet()) { combinedParams.append(delimiter); combinedParams.append(key); combinedParams.append("="); combinedParams.append(kvpParams.get(key)); delimiter="&"; } // url encode the entire string again before returning return URLEncoder.encode(combinedParams.toString(), "UTF-8"); } public static String hmacSha1(String value, String key) { String algorithm = "HmacSHA1"; try { // Get an hmac_sha1 key from the raw key bytes byte[] keyBytes = key.getBytes(); SecretKeySpec signingKey = new SecretKeySpec(keyBytes, algorithm); // Get an hmac_sha1 Mac instance and initialize with the signing key Mac mac = Mac.getInstance(algorithm); mac.init(signingKey); // Compute the hmac on input data bytes // byte[] rawHmac = mac.doFinal(value.getBytes()); // Convert raw bytes to Hex // byte[] hexBytes = new Hex().encode(rawHmac); return new String(Base64.encodeBase64(mac.doFinal(value.getBytes()))).trim(); // Covert array of Hex bytes to a String //return new String(hexBytes, "UTF-8"); } catch (Exception e) { throw new RuntimeException(e); } } }
pom.xml
<dependencies> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.10</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.0</version> </dependency>
以下のようにリクエストボディを送信して上記のプログラムを試し、 0YI3mBg7gmnWaz8YyISG4IoHVQ4=として oauth 署名を取得しましたが、期待されるのはyuuvR1pVDm5xWOYhMtBcBBVTdf8=です
どこが間違っているのか教えてください..