0

I've been trying to establish a connection with an API for more than a week now, to no avail. (Magic Card Market's, authentification documentation here and there). I'm supposed to receive a XML file.

I have what MCM call a "widget" access to their API, meaning that I don't have nor need a oauth_token (it's supposed to be an empty string) for the authorization header, and that I'm not supposed to receive nor use an access token/access secret.

The only things I do have are a consumer key (they call it app token sometimes) and a consumer secret.

Here is how I build my Authorization header :

private static String buildOAuthAuthorization(String method, String request)
        throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {

    String mkmAppToken = APICredentials.appToken;
    String mkmAppSecret = APICredentials.appSecret;

    String realm = "https://www.mkmapi.eu/ws/v1.1/games";
    String oauthVersion = "1.0";
    String oauthConsumerKey = mkmAppToken;
    String oauthToken = "";
    String oauthSignatureMethod = "HMAC-SHA1";
    String oauthTimestamp = Long.toString(System.currentTimeMillis() / 1000);
    String oauthNonce = Long.toString(System.currentTimeMillis());

    String paramString = "oauth_consumer_key=" + oauthConsumerKey
            + "oauth_nonce=" + oauthNonce
            + "oauth_signature_method=" + oauthSignatureMethod
            + "oauth_timestamp=" + oauthTimestamp
            + "oauth_token=" + oauthToken
            + "oauth_version=" + oauthVersion;

    String baseString = method + "&" + rawUrlEncode(realm) + "&" + rawUrlEncode(paramString);

    String signingKey = rawUrlEncode(mkmAppSecret) + "&";

    Mac mac = Mac.getInstance("HMAC-SHA1");
    SecretKeySpec secret = new SecretKeySpec(signingKey.getBytes(), mac.getAlgorithm());
    mac.init(secret);
    byte[] digest = mac.doFinal(baseString.getBytes());
    byte[] oauthSignature = Base64.encode(digest, Base64.URL_SAFE);

    String authorizationProperty = "OAuth "
            + "realm=\"" + realm + "\", "
            + "oauth_version=\"" + oauthVersion + "\", "
            + "oauth_timestamp=\"" + oauthTimestamp + "\", "
            + "oauth_nonce=\"" + oauthNonce + "\", "
            + "oauth_consumer_key=\"" + oauthConsumerKey + "\", "
            + "oauth_token=\""+ oauthToken + "\", "
            + "oauth_signature_method=\"" + oauthSignatureMethod + "\", "
            + "oauth_signature=\"" + oauthSignature + "\"";

    System.out.println(authorizationProperty);

    return authorizationProperty;
}

The actual request is in an AsyncTask :

public static class oAuthRequest extends AsyncTask<String, Integer, StringReader> {

    private int lastCode;

    @Override
    protected StringReader doInBackground(String... requestURLs) {

        String method = requestURLs[0];
        String url = requestURLs[1];
        StringReader result = null;

        try {

            String authProperty = buildOAuthAuthorization(method, url);
            HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
            connection.addRequestProperty("Authorization:", authProperty);

            lastCode = connection.getResponseCode();
            System.out.println("RESPONSE CODE 1 " + lastCode);

            // Get content
            BufferedReader rd = new BufferedReader(new InputStreamReader(lastCode == 200 ? connection.getInputStream() : connection.getErrorStream()));
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = rd.readLine()) != null) {
                sb.append(line);
            }
            rd.close();
            result = new StringReader(sb.toString());

        } catch (NoSuchAlgorithmException | InvalidKeyException | IOException e) {
            e.printStackTrace();
        }

        return result;
    }
}

It seems like no matter what I change, I'm always getting a 401.

Things I've tried :

  • oauthSignature as a String using Base64.encodeToString()
  • Nonce generation using SecureRandom
  • With and without the empty oauthToken
  • Another timestamp generation method (can't remember what though)
  • signing key with and without app token (theorically I need only the consumer secret, but you never know)
  • Using HttpsURLConnection instead of HttpURLConnection (the URI start in https, so I thought, hey. But no)
  • At least 2-3 other different implementations (one who was basically a copy/paste of the Java example in the documentation of course -- it still kind of is one now)
  • (Probably a lot of things I can't even remember)

At this point I'm wondering if maybe the issue comes from my keys, as I've tried to use the Postman app to test requests with the same results.

  • I'm working with the same API, via a Dedicated App right now though. For the games overview I needed both app and access tokens to access it, I understand you don't have access tokens with a widget though. Have you tried other resources? Like information of a specific card for example. In summary I think the API is quite a pain to work with. Additional question, how long did it take for you to get our Widget App keys? – skiwi Aug 10 '16 at 12:22
  • I suspect the issue is in `rawUrlEncode` as that also gave me various issues, can you post the code for that? – skiwi Aug 10 '16 at 12:28
  • did you ever get this working? – andli Aug 16 '18 at 12:57

0 Answers0