在Android应用程序上无法获得对Amazon alexa的授权令牌访问权限

时间:2017-06-23 13:18:08

标签: android httpclient alexa alexa-voice-service

我创建了一个安全配置文件并从中获取了CODE_CHALLENGE。我引用了How to Authenticate with Alexa Voice Service from Android?

private static final String PRODUCT_ID = "my_device";
private static final String PRODUCT_DSN = "123";
private static final String CODE_CHALLENGE = "ca9416f4aaafc68f0722e38410f9acd18094a9b9f59e0c10a1cf8930b3d8600f";
private static final String CODE_CHALLENGE_METHOD = "S256";


 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_amazon_login);

    requestContext = RequestContext.create(this);
    requestContext.registerListener(new AuthorizeListenerImpl());

    buttonAmazon = (Button)findViewById(R.id.button_amazon);
    buttonAmazon.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            final JSONObject scopeData = new JSONObject();
            final JSONObject productInstanceAttributes = new JSONObject();

            try {
                productInstanceAttributes.put("deviceSerialNumber", PRODUCT_DSN);
                scopeData.put("productInstanceAttributes", productInstanceAttributes);
                scopeData.put("productID", PRODUCT_ID);

                AuthorizationManager.authorize(new AuthorizeRequest.Builder(requestContext)
                        .addScope(ScopeFactory.scopeNamed("alexa:all", scopeData))
                        .forGrantType(AuthorizeRequest.GrantType.AUTHORIZATION_CODE)
                        .withProofKeyParameters(CODE_CHALLENGE, CODE_CHALLENGE_METHOD)
                        .build());
            } catch (JSONException e) {
                // handle exception here
            }

        }
    });
}
private class AuthorizeListenerImpl extends AuthorizeListener {

    /* Authorization was completed successfully. */
    @Override
    public void onSuccess(final AuthorizeResult authorizeResult) {
        final String authorizationCode = authorizeResult.getAuthorizationCode();
        final String redirectUri = authorizeResult.getRedirectURI();
        final String clientId = authorizeResult.getClientId();
        Log.d("AmazonLoginActivity","success"+" "+authorizationCode+" "+redirectUri+" "+clientId);
        postData(authorizationCode,redirectUri,clientId);

    }

    /* There was an error during the attempt to authorize the application. */
    @Override
    public void onError(final AuthError authError) {
    }

    /* Authorization was cancelled before it could be completed. */
    @Override
    public void onCancel(final AuthCancellation authCancellation) {
    }
}


public void postData(String s1, String s2, String s3) {
    HttpClient httpclient = new DefaultHttpClient();
    HttpPost httppost = new HttpPost("https://api.amazon.com/auth/O2/token");

    try {
        // Add your data
        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
        nameValuePairs.add(new BasicNameValuePair("grant_type", "authorization_code"));
        nameValuePairs.add(new BasicNameValuePair("code", s1));
        nameValuePairs.add(new BasicNameValuePair("redirect_uri", s2));
        nameValuePairs.add(new BasicNameValuePair("client_id", s3));
        nameValuePairs.add(new BasicNameValuePair("code_verifier","1234"));
        httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

        // Execute HTTP Post Request
        HttpResponse response = httpclient.execute(httppost);
        String responseStr = EntityUtils.toString(response.getEntity());
        Header[] headers = response.getAllHeaders();
        for (Header header : headers) {
            System.out.println("Key : " + header.getName()
                    + " ,Value : " + header.getValue());
        }

        Log.d("Response",responseStr);


    } catch (ClientProtocolException e) {
        // TODO Auto-generated catch block
    } catch (IOException e) {
        // TODO Auto-generated catch block
    }
}

我正在收到unauthorized_client异常。这是我的安卓日志。

06-23 18:31:02.496 29161-29523/gct.venkatesh.com.alexabot I/com.amazon.identity.auth.device.authorization.AuthorizationHelper: Return auth code success 
06-23 18:31:02.500 29161-29523/gct.venkatesh.com.alexabot D/AmazonLoginActivity: success ANkBjQgTSnsVwfcQCqrU amzn://gct.venkatesh.com.alexabot amzn1.application-oa2-client.bd04c0584c0c4a1296bf3c1f14f9a831 
06-23 18:31:02.611 29161-29161/gct.venkatesh.com.alexabot I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy@1496318b time:21809219 
06-23 18:31:04.543 29161-29523/gct.venkatesh.com.alexabot I/System.out: Key : Server ,Value : Server 
06-23 18:31:04.544 29161-29523/gct.venkatesh.com.alexabot I/System.out: Key : Date ,Value : Fri, 23 Jun 2017 13:00:42 GMT 
06-23 18:31:04.544 29161-29523/gct.venkatesh.com.alexabot I/System.out: Key : Content-Type ,Value : application/json 
06-23 18:31:04.544 29161-29523/gct.venkatesh.com.alexabot I/System.out: Key : Content-Length ,Value : 92 
06-23 18:31:04.544 29161-29523/gct.venkatesh.com.alexabot I/System.out: Key : Connection ,Value : keep-alive 
06-23 18:31:04.544 29161-29523/gct.venkatesh.com.alexabot I/System.out: Key : x-amzn-RequestId ,Value : f6f231ed-5813-11e7-88b7-1d51a9cde1df 
06-23 18:31:04.544 29161-29523/gct.venkatesh.com.alexabot I/System.out: Key : X-Amz-Date ,Value : Fri, 23 Jun 2017 13:00:42 GMT 
06-23 18:31:04.544 29161-29523/gct.venkatesh.com.alexabot I/System.out: Key : x-amzn-ErrorType ,Value : OA2UnauthorizedClientException:http://internal.amazon.com/coral/com.amazon.panda/ 
06-23 18:31:04.544 29161-29523/gct.venkatesh.com.alexabot I/System.out: Key : Cache-Control ,Value : no-cache, no-store, must-revalidate 
06-23 18:31:04.544 29161-29523/gct.venkatesh.com.alexabot I/System.out: Key : Pragma ,Value : no-cache 
06-23 18:31:04.544 29161-29523/gct.venkatesh.com.alexabot I/System.out: Key : Vary ,Value : Accept-Encoding,User-Agent 
06-23 18:31:04.544 29161-29523/gct.venkatesh.com.alexabot D/Response: {"error_description":"Not authorized for requested operation","error":"unauthorized_client"

1 个答案:

答案 0 :(得分:-2)

@Venkatesh:

生成codeVerifier和codeChallenge:

String codeVerifier = generateCodeVerifier();
String codeChallenge = generateCodeChallenge(codeVerifier, "S256");







 private String generateCodeVerifier() {
                String randomOctetSequence = generateRandomOctetSequence(100);
                String codeVerifier = base64UrlEncode(randomOctetSequence.getBytes());
                return codeVerifier;
            }

            private String generateRandomOctetSequence(int count) {
                char[] chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-_.~".toCharArray();
                StringBuilder sb = new StringBuilder();
                Random random = new Random();
                for (int i = 0; i < count; i++) {
                    char c = chars[random.nextInt(chars.length)];
                    sb.append(c);
                }
                return sb.toString();
            }

    private String generateCodeChallenge(String codeVerifier, String codeChallengeMethod) {
                String codeChallenge = "";
                if ("S256".equalsIgnoreCase(codeChallengeMethod)) {
                    try {
                        byte[] digest = MessageDigest.getInstance("SHA-256").digest(
                                codeVerifier.getBytes());
                        codeChallenge = base64UrlEncode(
                                digest);
                    } catch (NoSuchAlgorithmException e) {
                        e.printStackTrace();
                    }
                } else {
                    // Fall back to code_challenge_method = "plain" codeChallenge = codeVerifier;
                }
                return codeChallenge;
            }

    private String base64UrlEncode(byte[] arg) {
                String s = new String(Base64.encode(arg, Base64.URL_SAFE | Base64.NO_PADDING | Base64.NO_WRAP));
                s = s.split("=")[0]; // Remove any trailing '='s
                s = s.replace('+', '-'); // 62nd char of encoding
                s = s.replace('/', '_'); // 63rd char of encoding
                return s;
            }

Plz在这里看到我的评论(来源):https://github.com/alexa/alexa-avs-sample-app/issues/987