在 Unity3D C# 中签署 AWS Api 网关请求
Signing AWS Api Gateway request in Unity3D C#
我正在使用 Unity3D v5.5.1 和 AWS-SDK-Unity v3.3.37.0。
由于 Api 网关不会为 C#/Unity3D 生成 SDK,我正在尝试自己签署 (SigV4) 请求,但遇到了困难。
我都试过了 manually signing and using the AWS4Signer.cs class。
Api 网关方法具有 使用调用方凭据调用 ,并且只是 returns Hello World 作为响应。
在 unity 中,我有一个 facebook 登录按钮,其中 returns FB 凭据和令牌。使用 Cognito Federated Identity 的 GetCredentialsAsync 方法,我得到一个 ImmutableCredentials 对象,其中包含 Key、Secret 和 Token。
要访问 api 网关 url 我在此处使用 AWS4Signer class 来构建签名请求。在下面的示例中,我已经尝试将安全令牌添加到 url 参数,并且不对它进行签名而不使用该令牌进行签名。所有选项都不起作用(如 中所述)
这会导致以下响应:
1.我们计算出的请求签名与您提供的签名不匹配
- 请求中包含的安全令牌无效。
如何正确签署来自 Unity3D 的请求?
提前致谢
测试获取方法:
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);
}
助手 classes:
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 () {}
}
已解决。
我创建了一些 示例 来展示如何执行此操作。仍在进行中,示例显示了如何签署来自 Unity 3D 的 POST 请求到具有 "Invoke with caller credentials" (AWS_IAM).
的 Api 网关端点
Unity 3D 客户端:
https://github.com/guywald/serverless-auth-msg-board-unity3d-client
AWS 无服务器后端(使用 Serverless Framework):
我正在使用 Unity3D v5.5.1 和 AWS-SDK-Unity v3.3.37.0。 由于 Api 网关不会为 C#/Unity3D 生成 SDK,我正在尝试自己签署 (SigV4) 请求,但遇到了困难。
我都试过了 manually signing and using the AWS4Signer.cs class。
Api 网关方法具有 使用调用方凭据调用 ,并且只是 returns Hello World 作为响应。
在 unity 中,我有一个 facebook 登录按钮,其中 returns FB 凭据和令牌。使用 Cognito Federated Identity 的 GetCredentialsAsync 方法,我得到一个 ImmutableCredentials 对象,其中包含 Key、Secret 和 Token。
要访问 api 网关 url 我在此处使用 AWS4Signer class 来构建签名请求。在下面的示例中,我已经尝试将安全令牌添加到 url 参数,并且不对它进行签名而不使用该令牌进行签名。所有选项都不起作用(如
这会导致以下响应: 1.我们计算出的请求签名与您提供的签名不匹配
- 请求中包含的安全令牌无效。
如何正确签署来自 Unity3D 的请求?
提前致谢
测试获取方法:
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);
}
助手 classes:
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 () {}
}
已解决。
我创建了一些 示例 来展示如何执行此操作。仍在进行中,示例显示了如何签署来自 Unity 3D 的 POST 请求到具有 "Invoke with caller credentials" (AWS_IAM).
的 Api 网关端点Unity 3D 客户端:
https://github.com/guywald/serverless-auth-msg-board-unity3d-client
AWS 无服务器后端(使用 Serverless Framework):