Blue Prism Product

 View Only
last person joined: yesterday 

This community covers the core Blue Prism RPA product.

  • 1.  API - AWS S3

    Posted 02-03-2020 12:55
    Hi Guys, 

    I'm trying to setup a Web API for AWS S3, but i'm struggling to get a response. 

    I've got it working using Postman, but I'm getting the error SignatureDoesNotMatch when using BP.

    I have downloaded and tweaked the AWS:Rekognition API to try and get this to work, but I don't think my Authorization Header is correct. I am using the code stage provided with the API to generation the header, with a couple of tweaks, but I'm not sure i'm doing it correctly.

    Code


    Has anyone done this before or can anyone point me in the right direction?

    Thanks

    ------------------------------
    Dan Lister
    Developer
    Europe/London
    ------------------------------


  • 2.  RE: API - AWS S3

    Posted 02-04-2020 08:35
    Hi,

    What is the response code and message that you get from AWS?

    ------------------------------
    Shashank Kumar
    DX Integrations Partner Consultant
    Blue Prism
    Singapore
    +6581326707
    ------------------------------



  • 3.  RE: API - AWS S3

    Posted 02-04-2020 08:42
    Hi,

    Thanks for responding.

    Response Code is :-

    HTTP Status Code: 403
    HTTP Response Content: SignatureDoesNotMatch
    The request signature we calculated does not match the signature you provided. Check your key and signing method.

    Thanks


    ------------------------------
    Dan Lister
    Developer
    Arvato
    Europe/London
    ------------------------------



  • 4.  RE: API - AWS S3

    Posted 02-04-2020 12:52
    Hi Dan,

    It seems the signature passed from the vbo isn't matching with the POSTMAN request. Would you be able to share the screenshot of POSTMAN and the web api file?

    ------------------------------
    Shashank Kumar
    DX Integrations Partner Consultant
    Blue Prism
    Singapore
    +6581326707
    ------------------------------



  • 5.  RE: API - AWS S3

    Posted 02-04-2020 14:44
    Hi, 

    I'm afraid I can't attach the Web API file, but here is the Postman Screenshot:

    Postman



    Thanks

    ------------------------------
    Dan Lister
    Developer
    Arvato
    Europe/London
    ------------------------------



  • 6.  RE: API - AWS S3

    Posted 02-05-2020 10:24
    Hi, 

    I've just realised that I hadn't edited the Global Code on that object and it looks that this is set up for a POST request. I've tried tweaking again, but my knowledge just isn't good enough to understand and ensure I'm doing it correctly.

    I've been trying to follow this guide, but having no luck. https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html

    Can anyone help?

    Thanks

    Global Code
    // SHA256 hash of an empty request body
    public string EMPTY_BODY_SHA256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
    
    public string SCHEME = "AWS4";
    public string ALGORITHM = "HMAC-SHA256";
    public string TERMINATOR = "aws4_request";
    
    // format strings for the date/time and date stamps required during signing
    public string ISO8601BasicFormat = "yyyyMMddTHHmmssZ";
    public string DateStringFormat = "yyyyMMdd";
    
    // some common x-amz-* parameters
    string X_Amz_Algorithm = "X-Amz-Algorithm";
    string X_Amz_Credential = "X-Amz-Credential";
    string X_Amz_SignedHeaders = "X-Amz-SignedHeaders";
    string X_Amz_Date = "X-Amz-Date";
    string X_Amz_Signature = "X-Amz-Signature";
    string X_Amz_Expires = "X-Amz-Expires";
    string X_Amz_Content_SHA256 = "X-Amz-Content-SHA256";
    string X_Amz_Decoded_Content_Length = "X-Amz-Decoded-Content-Length";
    string X_Amz_Meta_UUID = "X-Amz-Meta-UUID";
    
    // the name of the keyed hash algorithm used in signing
    string HMACSHA256 = "HMACSHA256";
    
    Regex CompressWhitespaceRegex = new Regex("\\s+");
    
    string strAction = "POST";
    Uri uri;
    
    HashAlgorithm CanonicalRequestHashAlgorithm = HashAlgorithm.Create("SHA-256");
    
    public string ComputeSignature(IDictionary<string, string> headers,
                                string dateTimeStamp,   
    			    string queryParameters,
                                string bodyHash,
                                string awsAccessKey,
                                string awsSecretKey,
    			    string awsUri,
    			    string awsRegion,
    			    string awsService)
    {
        
    	// first get the date and time for the subsequent request, and convert to ISO 8601 format
        // for use in signature generation
        var requestDateTime = DateTime.UtcNow;
    
        // update the headers with required 'x-amz-date' and 'host' values
        headers.Add(X_Amz_Date, dateTimeStamp);
    
        uri = new Uri(awsUri);
    	var hostHeader = uri.Host;
        if (!uri.IsDefaultPort)
            hostHeader += ":" + uri.Port;
        headers.Add("Host", hostHeader);
    
        // canonicalize the headers; we need the set of header names as well as the
        // names and values to go into the signature process
        var canonicalizedHeaderNames = CanonicalizeHeaderNames(headers);
        var canonicalizedHeaders = CanonicalizeHeaders(headers);
    
        // canonicalize the various components of the request
        var canonicalRequest = CanonicalizeRequest(uri,
                                                   strAction,
                                                   null,
                                                   canonicalizedHeaderNames,
                                                   canonicalizedHeaders,
                                                   bodyHash);
    
        // generate a hash of the canonical request, to go into signature computation
        var canonicalRequestHashBytes
            = CanonicalRequestHashAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(canonicalRequest));
    
        // construct the string to be signed
        var stringToSign = new StringBuilder();
    
        var dateStamp = requestDateTime.ToString(DateStringFormat, CultureInfo.InvariantCulture);
        var scope = string.Format("{0}/{1}/{2}/{3}",
                                  dateStamp,
                                  awsRegion,
                                  awsService,
                                  TERMINATOR);
    
        stringToSign.AppendFormat("{0}-{1}\n{2}\n{3}\n", SCHEME, ALGORITHM, dateTimeStamp, scope);
        stringToSign.Append(ToHexString(canonicalRequestHashBytes, true));
    
        // compute the signing key
        var kha = KeyedHashAlgorithm.Create(HMACSHA256);
        kha.Key = DeriveSigningKey(HMACSHA256, awsSecretKey, awsRegion, dateStamp, awsService);
    
        // compute the AWS4 signature and return it
        var signature = kha.ComputeHash(Encoding.UTF8.GetBytes(stringToSign.ToString()));
        var signatureString = ToHexString(signature, true);
        //Console.WriteLine("\nSignature:\n{0}", signatureString);
    
        var authString = new StringBuilder();
        authString.AppendFormat("{0}-{1} ", SCHEME, ALGORITHM);
        authString.AppendFormat("Credential={0}/{1}, ", awsAccessKey, scope);
        authString.AppendFormat("SignedHeaders={0}, ", canonicalizedHeaderNames);
        authString.AppendFormat("Signature={0}", signatureString);
    
        var authorization = authString.ToString();
    
        return authorization;
    }
    public string CanonicalizeRequest(Uri endpointUri,
                                 string httpMethod,
                                 string queryParameters,
                                 string canonicalizedHeaderNames,
                                 string canonicalizedHeaders,
                                 string bodyHash)
    {
        var canonicalRequest = new StringBuilder();
    
        canonicalRequest.AppendFormat("{0}\n", httpMethod);
        canonicalRequest.AppendFormat("{0}\n", CanonicalResourcePath(endpointUri));
        canonicalRequest.AppendFormat("{0}\n", queryParameters);
    
        canonicalRequest.AppendFormat("{0}\n", canonicalizedHeaders);
        canonicalRequest.AppendFormat("{0}\n", canonicalizedHeaderNames);
    
        canonicalRequest.Append(bodyHash);
    
        return canonicalRequest.ToString();
    }
    public string CanonicalResourcePath(Uri endpointUri)
    {
        if (string.IsNullOrEmpty(endpointUri.AbsolutePath))
            return "/";
    
        // encode the path per RFC3986
        return UrlEncode(endpointUri.AbsolutePath, true);
    }
    public byte[] DeriveSigningKey(string algorithm, string awsSecretAccessKey, string awsRegion, string date, string awsService)
    {
        string ksecretPrefix = SCHEME;
        char[] ksecret = null;
    
        ksecret = (ksecretPrefix + awsSecretAccessKey).ToCharArray();
    
        byte[] hashDate = ComputeKeyedHash(algorithm, Encoding.UTF8.GetBytes(ksecret), Encoding.UTF8.GetBytes(date));
        byte[] hashRegion = ComputeKeyedHash(algorithm, hashDate, Encoding.UTF8.GetBytes(awsRegion));
        byte[] hashService = ComputeKeyedHash(algorithm, hashRegion, Encoding.UTF8.GetBytes(awsService));
        return ComputeKeyedHash(algorithm, hashService, Encoding.UTF8.GetBytes(TERMINATOR));
    }
    public byte[] ComputeKeyedHash(string algorithm, byte[] key, byte[] data)
    {
        var kha = KeyedHashAlgorithm.Create(algorithm);
        kha.Key = key;
        return kha.ComputeHash(data);
    }
    public string CanonicalizeHeaderNames(IDictionary<string, string> headers)
    {
        var headersToSign = new List<string>(headers.Keys);
        headersToSign.Sort(StringComparer.OrdinalIgnoreCase);
    
        var sb = new StringBuilder();
        foreach (var header in headersToSign)
        {
            if (sb.Length > 0)
                sb.Append(";");
            sb.Append(header.ToLower());
        }
        return sb.ToString();
    }
    public string CanonicalizeHeaders(IDictionary<string, string> headers)
    {
        if (headers == null || headers.Count == 0)
            return string.Empty;
    
        // step1: sort the headers into lower-case format; we create a new
        // map to ensure we can do a subsequent key lookup using a lower-case
        // key regardless of how 'headers' was created.
        var sortedHeaderMap = new SortedDictionary<string, string>();
        foreach (var header in headers.Keys)
        {
            sortedHeaderMap.Add(header.ToLower(), headers[header]);
        }
    
        // step2: form the canonical header:value entries in sorted order. 
        // Multiple white spaces in the values should be compressed to a single 
        // space.
        var sb = new StringBuilder();
        foreach (var header in sortedHeaderMap.Keys)
        {
            var headerValue = CompressWhitespaceRegex.Replace(sortedHeaderMap[header], " ");
            sb.AppendFormat("{0}:{1}\n", header, headerValue.Trim());
        }
    
        return sb.ToString();
    }
    public string UrlEncode(string data, bool isPath = false)
    {
        // The Set of accepted and valid Url characters per RFC3986. Characters outside of this set will be encoded.
        const string validUrlCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~";
    
        var encoded = new StringBuilder(data.Length * 2);
        string unreservedChars = String.Concat(validUrlCharacters, (isPath ? "/:" : ""));
    
        foreach (char symbol in System.Text.Encoding.UTF8.GetBytes(data))
        {
            if (unreservedChars.IndexOf(symbol) != -1)
                encoded.Append(symbol);
            else
                encoded.Append("%").Append(String.Format("{0:X2}", (int)symbol));
        }
    
        return encoded.ToString();
    }
    public string ToHexString(byte[] data, bool lowercase)
    {
        var sb = new StringBuilder();
        for (var i = 0; i < data.Length; i++)
        {
            sb.Append(data[i].ToString(lowercase ? "x2" : "X2"));
        }
        return sb.ToString();
    }

    AuthSignature Code Stage

    string strBody = RequestBody;
    
    // precompute hash of the body content            
    var contentHash = CanonicalRequestHashAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(strBody));
    var contentHashString = ToHexString(contentHash, true);
    
    var requestDateTime = DateTime.UtcNow;
    var dateTimeStamp = requestDateTime.ToString(ISO8601BasicFormat, CultureInfo.InvariantCulture);
    strAuthDate = dateTimeStamp;
    
    var headers = new Dictionary<string, string>
                {
                    {"content-type", "application/x-amz-json-1.1"},
                    {"x-amz-target", AWSTarget}
                };
    
    strAuthSignature = ComputeSignature(headers,
           			      dateTimeStamp,
                                  "",   // no query parameters
                                  contentHashString,
                                  AccessID,
                                  SecretKey,
                                  AWSEndpoint,
    			      AWSRegion,
                                  AWSService);


    ------------------------------
    Dan Lister
    Developer
    Arvato
    Europe/London
    ------------------------------



Welcome to the Blue Prism RPA Product Community!

Whether you’re looking to manage a complex infrastructure, maintain security and compliance, bring new products to market faster, or gain operational speed and agility in an uncertain economy, Blue Prism delivers — with the flexibility you need to create the business you want. From deployment on-premise, through a cloud service provider or as SaaS, to a skillful and adaptable digital workforce that continually expands to meet your enterprise needs, you can gain enhanced operational insight and control while your people reclaim the time they need to focus on great work.

Product PageKnowledge BaseBlue Prism Training Offering
Product Research ProgramUpdates, Releases & Announcements

FAQs

Blue Prism is intelligent automation — business-developed, no-code automation that pushes the boundaries of robotic process automation (RPA) to deliver value across any business process in a connected enterprise.

A combination of RPA with expanded cognitive and AI capabilities, Blue Prism is different than other automation technology on the market. With one Blue Prism license, you gain instant access to an already AI equipped digital workforce, along with the tools you need to build and delegate automations. Click here for more information on Blue Prism and Intelligent Automation.
To learn more about how Blue Prism RPA can help your organization and how much it will cost to get started, please Contact our Sales department.
Blue Prism RPA can be downloaded from our customer portal. If you would like to consume or download any material it is necessary to create an account on the Portal. Once you have registered, you can access the download options for Blue Prism here.
Yes! Installed on your own machine and supported by our training materials and product documentation, you can use all the features of the full enterprise product for free with our Blue Prism Trial – giving you the opportunity to learn the basics before moving to a full production implementation. Click here for more information and to download the trial.
Yes! You can access our known issue list for Blue Prism from our Support Portal.
Regardless of your industry, Blue Prism’s Digital Workforce can adhere to strict governance and compliance standards without limiting productivity. Click here for more information on how your industry can benefit from Blue Prism.