简体   繁体   中英

Unable to load credentials from any of the providers in the chain AwsCredentialsProviderChain

I'm getting the following exception when trying to read a file to AWS S3 Error:

Unable to load AWS credentials from any provider in the chain.

I have generated a public bucket and also generated an AWS IAM role with full S3 bucket access and textract access.

I am trying to read an image from S3 bucket and run AWS Textract service.

Java code:

package com.textract;

import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.services.s3.model.S3ObjectInputStream;
import software.amazon.awssdk.core.SdkBytes;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.textract.TextractClient;
import software.amazon.awssdk.services.textract.model.*;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;


public class App {

    public static Map<String, String> getRelationships(Map<String, Block> blockMap, Map<String, Block> keyMap,Map<String, Block> valueMap) {
        Map<String, String> result = new LinkedHashMap<>();
        for(Map.Entry<String, Block> itr : keyMap.entrySet()) {
            Block valueBlock = findValue(itr.getValue(), valueMap);
            String key = getText(itr.getValue(), blockMap);
            String value = getText(valueBlock, blockMap);
            result.put(key, value);
        }
        return result;
    }

    public static Block findValue(Block keyBlock, Map<String, Block> valueMap) {
        Block b = null;
        for(Relationship relationship : keyBlock.relationships()) {
            if(relationship.type().toString().equals("VALUE")) {
                for(String id : relationship.ids()) {
                    b = valueMap.get(id);
                }
            }
        }
        return b;
    }

    public static String getText(Block result, Map<String, Block> blockMap) {
        StringBuilder stringBuilder = new StringBuilder();
        for(Relationship relationship : result.relationships()) {
            if(relationship.type().toString().equals("CHILD")) {
                for(String id : relationship.ids()) {
                    Block b = blockMap.get(id);
                    if(b.blockTypeAsString().equals("WORD")) {
                        stringBuilder.append(b.text()).append(" ");
                    }
                 }
            }
        }
        return stringBuilder.toString();
    }

    public static void main(String[] args) {
        
        BasicAWSCredentials creds = new BasicAWSCredentials("<Secret Key>", "<Access Key>");
        AmazonS3 s3client = AmazonS3Client.builder()
                .withRegion("ap-southeast-1")
                .withCredentials(new AWSStaticCredentialsProvider(creds))
                .build();
        
//        AmazonS3 s3client = AmazonS3ClientBuilder.standard().build();
        S3Object s3Object = s3client.getObject("<S3 Bucket>", "image.jpg");
        S3ObjectInputStream s3ObjectInputStream = s3Object.getObjectContent();

        SdkBytes bytes = SdkBytes.fromInputStream(s3ObjectInputStream);
        Document doc = Document.builder().bytes(bytes).build();

        List<FeatureType> list = new ArrayList<>();
        list.add(FeatureType.FORMS);

        AnalyzeDocumentRequest request = AnalyzeDocumentRequest.builder().featureTypes(list).document(doc).build();

        TextractClient textractClient = TextractClient.builder().region(Region.US_WEST_2).build();

        AnalyzeDocumentResponse response = textractClient.analyzeDocument(request);
        List<Block> blocks = response.blocks();

        Map<String, Block> blockMap = new LinkedHashMap<>();
        Map<String, Block> keyMap = new LinkedHashMap<>();
        Map<String, Block> valueMap = new LinkedHashMap<>();

        for (Block b : blocks) {
            String block_id = b.id();
            blockMap.put(block_id, b);
            if(b.blockTypeAsString().equals("KEY_VALUE_SET")) {
                for(EntityType entityType : b.entityTypes()) {
                    if(entityType.toString().equals("KEY")) {
                        keyMap.put(block_id, b);
                    } else {
                        valueMap.put(block_id, b);
                    }
                }
            }
        }
            System.out.println(getRelationships(blockMap, keyMap, valueMap));
            textractClient.close();

    }
}

Console error:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Exception in thread "main" software.amazon.awssdk.core.exception.SdkClientException: Unable to load credentials from any of the providers in the chain AwsCredentialsProviderChain(credentialsProviders=[SystemPropertyCredentialsProvider(), EnvironmentVariableCredentialsProvider(), WebIdentityTokenCredentialsProvider(), ProfileCredentialsProvider(), ContainerCredentialsProvider(), InstanceProfileCredentialsProvider()]) : [SystemPropertyCredentialsProvider(): Unable to load credentials from system settings. Access key must be specified either via environment variable (AWS_ACCESS_KEY_ID) or system property (aws.accessKeyId)., EnvironmentVariableCredentialsProvider(): Unable to load credentials from system settings. Access key must be specified either via environment variable (AWS_ACCESS_KEY_ID) or system property (aws.accessKeyId)., WebIdentityTokenCredentialsProvider(): Either the environment variable AWS_WEB_IDENTITY_TOKEN_FILE or the javaproperty aws.webIdentityTokenFile must be set., ProfileCredentialsProvider(): Profile file contained no credentials for profile 'default': ProfileFile(profiles=[]), ContainerCredentialsProvider(): Cannot fetch credentials from container - neither AWS_CONTAINER_CREDENTIALS_FULL_URI or AWS_CONTAINER_CREDENTIALS_RELATIVE_URI environment variables are set., InstanceProfileCredentialsProvider(): Unable to load credentials from service endpoint.]
    at software.amazon.awssdk.core.exception.SdkClientException$BuilderImpl.build(SdkClientException.java:98)
    at software.amazon.awssdk.auth.credentials.AwsCredentialsProviderChain.resolveCredentials(AwsCredentialsProviderChain.java:112)
    at software.amazon.awssdk.auth.credentials.internal.LazyAwsCredentialsProvider.resolveCredentials(LazyAwsCredentialsProvider.java:45)
    at software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider.resolveCredentials(DefaultCredentialsProvider.java:104)
    at software.amazon.awssdk.awscore.client.handler.AwsClientHandlerUtils.createExecutionContext(AwsClientHandlerUtils.java:76)
    at software.amazon.awssdk.awscore.client.handler.AwsSyncClientHandler.createExecutionContext(AwsSyncClientHandler.java:68)
    at software.amazon.awssdk.core.internal.handler.BaseSyncClientHandler.lambda$execute$1(BaseSyncClientHandler.java:97)
    at software.amazon.awssdk.core.internal.handler.BaseSyncClientHandler.measureApiCallSuccess(BaseSyncClientHandler.java:167)
    at software.amazon.awssdk.core.internal.handler.BaseSyncClientHandler.execute(BaseSyncClientHandler.java:94)
    at software.amazon.awssdk.core.client.handler.SdkSyncClientHandler.execute(SdkSyncClientHandler.java:45)
    at software.amazon.awssdk.awscore.client.handler.AwsSyncClientHandler.execute(AwsSyncClientHandler.java:55)
    at software.amazon.awssdk.services.textract.DefaultTextractClient.analyzeDocument(DefaultTextractClient.java:215)
    at com.textract.App.main(App.java:83)

You are only passing the credentials to the S3 client. You aren't passing them to the Textract client. If you are creating the credentials provider manually like that, you will need to pass it to each client instance that is created.

I highly suggest using the environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY to provide credentials, instead of setting them directly in your code like that, as it will be much more flexible when you run this code in other environments, and will allow the AWS SDK to pick up the credentials automatically without the need for you to create a credentials provider at all.

I finally got it working with the below code with the below article:

Calling Amazon Textract Synchronous Operations

String document="input.png";
String bucket="bucket";

AmazonTextract client = AmazonTextractClientBuilder.defaultClient();

DetectDocumentTextRequest request = new DetectDocumentTextRequest()
        .withDocument(new Document()
                .withS3Object(new S3Object()
                        .withName(document)
                        .withBucket(bucket)));

DetectDocumentTextResult result = client.detectDocumentText(request);

Working Code

package aws.cloud.work;

import java.io.IOException;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.textract.AmazonTextract;
import com.amazonaws.services.textract.AmazonTextractClientBuilder;
import com.amazonaws.services.textract.model.DetectDocumentTextRequest;
import com.amazonaws.services.textract.model.DetectDocumentTextResult;
import com.amazonaws.services.textract.model.Document;
import com.amazonaws.services.textract.model.S3Object;

public class TextractOriginalMaster3 {

    static AmazonTextractClientBuilder clientBuilder = AmazonTextractClientBuilder.standard().withRegion(Regions.AP_SOUTHEAST_1);

    public static void main(String[] args) throws IOException {
       
        //Set AWS Credentials to use Textract
        clientBuilder.setCredentials(new AWSStaticCredentialsProvider(new
                BasicAWSCredentials("Accesskey", "Secretkey")));

        //**Getting document from S3 Bucket Path
        String document = "image.png";
        String bucket = "Bucket Name";

        //Calling AWS Textract Client
        AmazonTextract client = clientBuilder.build();
        DetectDocumentTextRequest request = new DetectDocumentTextRequest()
                .withDocument(new Document()
                        .withS3Object(new S3Object()
                                .withName(document)
                                .withBucket(bucket)));
        DetectDocumentTextResult result = client.detectDocumentText(request);
        System.out.println(result);
        result.getBlocks().forEach(block -> {
            if (block.getBlockType().equals("LINE"))
                System.out.println("text is " + block.getText() + " confidence is " + block.getConfidence());
        });
        
    }
}

To answer this, we can load the credentials using StaticCredentialsProvider Please refer the below code.

TextractClient textractClient = TextractClient.builder().region(Region.of(region)).credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials
            .create(accessKey,secretKey))).build();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM