2017-02-20 101 views
3

我正在使用Unity3D v5.5.1和AWS-SDK-Unity v3.3.37.0。 由於Api網關不生成C#/ Unity3D的SDK我試圖簽署(SigV4)請求我自己並遇到困難。在Unity3D中籤署AWS Api網關請求C#

我試過manually signing和使用AWS4Signer.cs類。

Api網關方法有調用呼叫者憑證,並剛剛返回一個Hello World作爲響應。

在統一內我有一個Facebook登錄按鈕,它返回FB憑據和令牌。使用Cognito聯合身份的GetCredentialsAsync方法我得到一個ImmutableCredentials對象與密鑰,祕密和令牌

訪問api網關url我在這裏使用AWS4Signer類來構造一個簽名的請求。在下面的例子中,我已經嘗試將安全令牌添加到url參數中,並且沒有對它進行簽名,也沒有使用令牌進行簽名。所有的選項都不起作用(如this post說明)

這將導致以下兩種對策: 1.我們計算出你所提供的簽名不匹配的請求籤名

  • 請求中包含的安全令牌無效。
  • 如何正確地簽署Unity3D的請求?

    預先感謝

    TestGet方法:

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

    Helper類:

    public class ApiGatewayConfig : ClientConfig 
        { 
         private static readonly string UserAgentString = 
          InternalSDKUtils.BuildUserAgentString("3.3.37.0"); 
    
         private string _userAgent = UserAgentString; 
    
    
         public ApiGatewayConfig() 
         { 
          this.AuthenticationServiceName = "execute-api"; 
         } 
    
    
         /// <summary> 
         /// The constant used to lookup in the region hash the endpoint. 
         /// </summary> 
         public override string RegionEndpointServiceName 
         { 
          get 
          { 
           return "execute-api"; 
          } 
         } 
    
         /// <summary> 
         /// Gets the ServiceVersion property. 
         /// </summary> 
         public override string ServiceVersion 
         { 
          get 
          { 
           return "2015-07-09"; 
          } 
         } 
    
         /// <summary> 
         /// Gets the value of UserAgent property. 
         /// </summary> 
         public override string UserAgent 
         { 
          get 
          { 
           return _userAgent; 
          } 
         } 
    
        } 
    
        public class MyRequest : AmazonWebServiceRequest 
        { 
         public MyRequest() {} 
        } 
    

    回答

    1

    解決。

    我創建了一些示例顯示瞭如何執行此操作。仍在進行中,示例顯示如何將Unity 3D中的POST請求籤署到具有「調用者憑據調用」(AWS_IAM)的Api網關端點。

    統一的3D客戶端:

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

    AWS無服務器後端(使用Serverless Framework):

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

    +0

    謝謝分享@Guy!我正在爲我的Unity3d遊戲選擇雲提供商,並在考慮將API Gateway用於無服務器後端時遇到您的帖子。到目前爲止如何?您是否在調用API網關調用並將AWS整體用於遊戲後端?願意知道! – dferraro

    +0

    那麼無服務器呢?直到我看到您的帖子才從未聽說過。它看起來很神奇。 Unity3d整合如何?爲什麼不使用API​​網關? – dferraro

    +0

    無服務器框架使您能夠創建AWS Api網關端點並讓它們調用lambda函數。有了這個框架,定義和部署它就更容易了。還有其他工具,如SAM(無服務器應用程序模型)。這些工具將Api網關端點(REST的url)和lambda的定義放在JSON/YAML中定義您的REST Api的相同位置。 另一方面,您不需要帶Api Gateway的REST Api來訪問AWS服務,這可以直接通過AWS SDK完成。 –