在Unity3D C#中签署AWS Api网关请求

时间:2017-02-20 22:05:08

标签: unity3d aws-lambda aws-api-gateway facebook-unity-sdk

我正在使用Unity3D v5.5.1和AWS-SDK-Unity v3.3.37.0。 由于Api Gateway没有为C#/ Unity3D生成SDK,我试图签署(SigV4)我自己的请求并遇到了困难。

我已尝试manually signing并使用AWS4Signer.cs类。

Api Gateway方法具有 Invoke with caller credentials ,只返回Hello World作为响应。

在团结中我有一个facebook登录按钮,它返回FB凭据和令牌。使用Cognito Federated Identity的 GetCredentialsAsync 方法,我使用密钥,密钥和令牌获得 ImmutableCredentials 对象。

要访问api网关网址,我在这里使用AWS4Signer类来构建签名请求。在下面的示例中,我尝试将安全令牌添加到url参数中,并且没有签名,也没有使用令牌进行签名。所有选项都不起作用(如this post中所述)

这导致以下响应: 1.我们计算的请求签名与您提供的签名不匹配

  1. 请求中包含的安全令牌无效。
  2. 如何正确签署Unity3D的请求?

    提前致谢

    TestGet方法:

        <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>@ViewBag.Title - blah blah blah</title>
        @Styles.Render("~/Content/css")
        @Scripts.Render("~/bundles/modernizr")
    </head>
    <body>
        <div class="navbar">
            <div class="container">
                <div class="navbar-header">
                    <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                    </button>
                    @Html.ActionLink("IHS Data Manager", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li>@Html.ActionLink("Home", "Index", "Home")</li>
                    <li>@Html.ActionLink("About", "About", "Home")</li>
                    <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
                </ul>
                <p class="nav navbar-text navbar-right">@User.Identity.Name</p>
            </div>
        </div>
    </div>
    <div class="container body-content">
        @RenderBody()
        <hr />
        <footer>blah blah blahMorningStar Partners LP</p>
        </footer>
    </div>
    
        @Scripts.Render("~/bundles/IDM")
    
        @RenderSection("scripts", required: false)
    </body>
    </html>
    

    助手类:

    IEnumerator TestGet (ImmutableCredentials response)
            {
                ApiGatewayConfig clientConfig = new ApiGatewayConfig(); // a class I created wrapping the ClientConfig.cs
                var metrics = new RequestMetrics();
    
                var awsAccessKeyId = response.AccessKey;
                var awsSecretAccessKey = response.SecretKey;
                var awsToken = response.Token;
    
                AmazonWebServiceRequest req = new MyRequest(); // a clas I created wrapping the AmazonWebServiceRequest.cs class
    
                var url = "https://<url_to_api>.execute-api.us-east-1.amazonaws.com/dev/securehello";
    
                IRequest request = new DefaultRequest(req,"execute-api");
                request.UseQueryString = true;
    
                request.HttpMethod = "GET";
                request.Endpoint = new System.Uri (url);
                request.ResourcePath = url;
                request.ContentStream = new MemoryStream();
                request.Parameters.Add("X-Amz-Expires",AWS4PreSignedUrlSigner.MaxAWS4PreSignedUrlExpiry.ToString(CultureInfo.InvariantCulture));
    
                request.AuthenticationRegion = "us-east-1";
                request.AlternateEndpoint = RegionEndpoint.USEast1;
                request.UseSigV4 = true;
                request.Headers.Add("X-Amz-Security-Token",awsToken);
                request.Parameters.Add("X-Amz-Security-Token",awsToken);
    
    
                AWS4Signer signer = new AWS4Signer();
                Debug.Log ("a");
                signer.Sign(request,clientConfig,metrics,awsAccessKeyId,awsSecretAccessKey);
                var signerRes = signer.SignRequest(request,clientConfig,metrics,awsAccessKeyId,awsSecretAccessKey);
                Debug.Log ("b");
                var myParams =  string.Format("{0}&X-Amz-Security-Token={1}",signerRes.ForQueryParameters,awsToken);
                var dict = myParams.Split('&').Select(p=> p.Split('=')).GroupBy(p => p[0]).Select(p => p.First()).ToDictionary(p => p[0], p=>System.Uri.UnescapeDataString(p[1]));
                var myEncodedParams = string.Empty;
                bool isFirst = true;
                foreach (var key in dict.Keys) {
                    myEncodedParams += string.Format("{0}{1}={2}",isFirst ? "" : "&",key,WWW.EscapeURL(dict[key]));
                    isFirst = false;
                }
    
                var finalUrl = string.Format ("{0}?{1}", request.Endpoint.AbsoluteUri,myEncodedParams);
    
                UnityWebRequest uwr = new UnityWebRequest (finalUrl, "GET", new DownloadHandlerBuffer (), null);
                Debug.Log ( string.Format("\n\n\n{0}\n\n\n",finalUrl));
                Debug.Log ("Starting WebRequest");
    
                yield return uwr.Send();
                if (uwr.isError) {
                    Debug.LogError (uwr.error);
                } else {
                    Debug.Log (uwr.downloadHandler.text);   
                }
    

1 个答案:

答案 0 :(得分:1)

<强>解决。

我已经创建了一些示例,展示了如何执行此操作。仍在进行中,示例显示如何从Unity 3D签署POST请求到Api Gateway端点,该端点具有“使用呼叫者凭证调用”(AWS_IAM)。

Unity 3D客户端:

https://github.com/guywald/serverless-auth-msg-board-unity3d-client

AWS无服务器后端(使用Serverless Framework):

https://github.com/guywald/serverless-auth-msg-board