【问题标题】:Cannot get authorization token access to Amazon alexa on android app无法在 Android 应用程序上获取对 Amazon Alexa 的授权令牌访问权限
【发布时间】:2023-03-31 04:11:01
【问题描述】:

我创建了一个安全配置文件并从中获得了 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
    }
}

我得到了未授权客户端异常。这是我的 android 日志。

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"

【问题讨论】:

    标签: android httpclient alexa alexa-voice-service


    【解决方案1】:

    @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;
                }
    

    请在此处查看我的评论(来源):https://github.com/alexa/alexa-avs-sample-app/issues/987

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-05
    • 1970-01-01
    • 1970-01-01
    • 2021-06-06
    • 2017-10-23
    • 1970-01-01
    • 2018-06-13
    相关资源
    最近更新 更多