【问题标题】:Cloud Speech API return code=UNAUTHENTICATED, cause =java.io.IOException: Error getting access token for service account:Cloud Speech API 返回码 = UNAUTHENTICATED,原因 =java.io.IOException:获取服务帐户的访问令牌时出错:
【发布时间】:2016-09-28 20:33:41
【问题描述】:

我使用 Google Cloud Speech API(通过 gRPC 的 StreamingRecognize)在我的应用中进行语音识别。我遇到了在 Android 设备 API 级别

V/NativeCrypto: SSL handshake aborted: ssl=0x5b0ed2d0: Failure in SSL library, usually a protocol error
                                                                 error:10000095:SSL routines:OPENSSL_internal:ERROR_PARSING_EXTENSION (third_party/openssl/boringssl/src/ssl/t1_lib.c:2336 0x5b0fcd50:0x00000001)
                                                                 error:100000be:SSL routines:OPENSSL_internal:PARSE_TLSEXT (third_party/openssl/boringssl/src/ssl/handshake_client.c:893 0x5aca7d31:0x00000000)

V/NativeCrypto: SSL shutdown failed: ssl=0x5b0ed2d0: Failure in SSL library, usually a protocol error
                                                                 error:100000fa:SSL routines:OPENSSL_internal:SHUTDOWN_WHILE_IN_INIT (third_party/openssl/boringssl/src/ssl/ssl_lib.c:703 0x5aca7d31:0x00000000)

V/NativeCrypto: SSL handshake aborted: ssl=0x58523fb8: Failure in SSL library, usually a protocol error
                                                                 error:1000042e:SSL routines:OPENSSL_internal:TLSV1_ALERT_PROTOCOL_VERSION (third_party/openssl/boringssl/src/ssl/tls_record.c:469 0x5b258bd8:0x00000001)

V/NativeCrypto: SSL shutdown failed: ssl=0x58523fb8: Failure in SSL library, usually a protocol error
                                                                 error:100000fa:SSL routines:OPENSSL_internal:SHUTDOWN_WHILE_IN_INIT (third_party/openssl/boringssl/src/ssl/ssl_lib.c:703 0x5aca7d31:0x00000000)

Status{code=UNAUTHENTICATED, description=null, cause=java.io.IOException: Error getting access token for service account: }

我不会每次都收到此错误,但仅限于特定情况。我有两个活动。让我们命名 A 和 B。

Activity A 有一个按钮,用于启动 Activity B。 Activity B 与 Google Cloud Speech API 通信并在 TextView 中显示结果。

执行以下步骤后出现此错误(在三星 GT-P5110 (Android 4.2.2) 上):

  1. 开始活动 A -> 按按钮开始活动 B。

// 第一次一切正常。我从服务器收到结果并显示。

  1. 关闭活动 B(按返回按​​钮或调用 onBackPressed 或完成)。

  2. 按下按钮启动活动 B。

// 此刻我得到错误,如上所示。

我在 Lenovo A1000 (API 5.0.1) 和 Xiaomi Mi4c (5.0.1) 上收到此错误:

  1. 启动 Activity A -> 按下按钮启动 Activity B。

  2. 关闭活动 B(按返回按​​钮或调用 onBackPressed 或完成)。

  3. 按下按钮启动活动 B。

//一切正常

  1. 关闭活动 B(按返回按​​钮或调用 onBackPressed 或完成)。

  2. 最小化应用程序。

  3. 5-6 分钟或更长时间后返回活动 A。

  4. 开始活动 B。

// 在这一刻我总是得到这个错误。

重启应用后一切正常,但重启Activity B后出现错误。

谁知道我该如何解决这个问题?

我使用 Play Services 动态安全提供程序 (It is required for gRPC)。 我安装了最新版本的 Google Play 服务(9.6.83)。它不能解决问题。

我通过以下代码创建 ManagedChannel:

GoogleCredentials creds = GoogleCredentials.fromStream(credentials);
    creds = creds.createScoped(OAUTH2_SCOPES);
    OkHttpChannelProvider provider = new OkHttpChannelProvider();
    OkHttpChannelBuilder builder = provider.builderForAddress(host, port);
ManagedChannel channel = builder.intercept(new ClientAuthInterceptor(creds, Executors
            .newSingleThreadExecutor
                    ()))
            .build();

private static final List<String> OAUTH2_SCOPES =
        Arrays.asList("https://www.googleapis.com/auth/cloud-platform");

创建 SpeechGrpc.SpeechStub :

SpeechGrpc.SpeechStub mSpeechClient = SpeechGrpc.newStub(channel);

build.gradle(模块:app)

apply plugin: 'com.android.application'
apply plugin: 'com.google.protobuf'

protobuf {
protoc {
    artifact = 'com.google.protobuf:protoc:3.0.0'
}
plugins {
    javalite {
        artifact = "com.google.protobuf:protoc-gen-javalite:3.0.0"
    }
    grpc {
        artifact = 'io.grpc:protoc-gen-grpc-java:1.0.1'
    }
}
generateProtoTasks {
    all().each { task ->
        task.plugins {
            javalite {}
            grpc {
                // Options added to --grpc_out
                option 'lite'
            }
        }
    }

}
}
android {
compileSdkVersion 24
buildToolsVersion "24.0.2"

dexOptions {
    javaMaxHeapSize "2048M"
}

defaultConfig {
    applicationId "someAppID"
    minSdkVersion 15
    targetSdkVersion 24
    versionCode 1
    versionName "1.0.10"
    multiDexEnabled true
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}
}

def grpcVersion = '1.0.1'

dependencies {
  compile fileTree(include: ['*.jar'], dir: 'libs')
  testCompile 'junit:junit:4.12'
  compile 'com.android.support:multidex:1.0.1'
  compile 'com.android.support:appcompat-v7:24.2.1'
  compile 'javax.annotation:javax.annotation-api:1.2'
  compile 'com.google.android.gms:play-services:9.6.0'
  compile "io.grpc:grpc-okhttp:${grpcVersion}"
  compile "io.grpc:grpc-protobuf:${grpcVersion}"
  compile "io.grpc:grpc-stub:${grpcVersion}"
  compile "io.grpc:grpc-auth:${grpcVersion}"
  compile ('com.google.auth:google-auth-library-oauth2-http:0.3.0'){
      exclude module: 'httpclient'
  }
  compile 'com.squareup.retrofit2:retrofit:2.1.0'
  compile 'com.squareup.retrofit2:converter-gson:2.1.0'
  compile 'com.itextpdf:itextg:5.5.9'
  compile 'com.android.support:recyclerview-v7:24.2.1'
}

build.gradle(项目)

buildscript {
repositories {
    jcenter()
}
dependencies {
    classpath 'com.android.tools.build:gradle:2.2.0'
    classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.0'

    // NOTE: Do not place your application dependencies here; they belong
    // in the individual module build.gradle files
}
}
allprojects {
repositories {
//        mavenLocal()
    jcenter()
}
}

task clean(type: Delete) {
delete rootProject.buildDir
}

感谢您的宝贵时间:)

【问题讨论】:

    标签: java android google-cloud-speech boringssl grpc-java


    【解决方案1】:

    我报告了这个问题in the forum

    出现问题的原因是您将服务帐户凭据嵌入到应用程序中。一段时间后,当内部刷新创建的token时,抛出错误来自:

    com.google.auth.oauth2.ServiceAccountCredentials.refreshAccessTokenlink

    在生产中,您将从您的服务器提供访问令牌,因此能够实例化 GoogleCredentials,如下所示:

        final GoogleCredentials googleCredentials = new GoogleCredentials(accessToken) {
            @Override
            public AccessToken refreshAccessToken() throws IOException {
                return accessToken;
            }
        }.createScoped(OAUTH2_SCOPES);
    

    这将防止错误被抛出。

    【讨论】:

    • 感谢您的回复。在最终应用程序(最终 apk)中嵌入服务帐户凭据是否危险?如果是,我如何在我的项目中安全地保存 credentials.json?我无法从服务器获取访问令牌,因为服务器不存在?
    • @Paukdcn 你不应该在你的应用程序中存储任何密钥,因为它可以被逆向工程。如果有人使用您的凭据,可能会花费您很多钱。 Firebase 非常适合此类任务。您将控制从那里分发临时访问令牌。这并不像听起来那么令人生畏,谷歌已经让这样的事情很容易集成到 Android 中。您将在几个小时内启动并运行它。
    猜你喜欢
    • 2021-12-02
    • 1970-01-01
    • 2014-09-08
    • 2021-10-14
    • 2020-08-03
    • 2015-02-11
    • 2017-10-07
    • 1970-01-01
    • 2015-04-29
    相关资源
    最近更新 更多