使用AWS .NET SDK示例SNS订阅确认

9
我正在尝试使用AWS .NET SDK来确认对SNS主题的订阅。此订阅通过HTTP完成,端点将位于.NET MVC网站中。我无法在任何地方找到.NET示例?提供一个可用的示例会很棒。我正在尝试类似以下的内容:
 Dim snsclient As New Amazon.SimpleNotificationService.AmazonSimpleNotificationServiceClient(ConfigurationSettings.AppSettings("AWSAccessKey"), ConfigurationSettings.AppSettings("AWSSecretKey"))

    Dim TopicArn As String = "arn:aws:sns:us-east-1:991924819628:post-delivery"


    If Request.Headers("x-amz-sns-message-type") = "SubscriptionConfirmation" Then

        Request.InputStream.Seek(0, 0)
        Dim reader As New System.IO.StreamReader(Request.InputStream)
        Dim inputString As String = reader.ReadToEnd()

        Dim jsSerializer As New System.Web.Script.Serialization.JavaScriptSerializer
        Dim message As Dictionary(Of String, String) = jsSerializer.Deserialize(Of Dictionary(Of String, String))(inputString)

        snsclient.ConfirmSubscription(New Amazon.SimpleNotificationService.Model.ConfirmSubscriptionRequest With {.AuthenticateOnUnsubscribe = False, .Token = message("Token"), .TopicArn = TopicArn})


   End If
5个回答

11

这是一个使用MVC WebApi 2和最新的AWS .NET SDK的工作示例。

var jsonData = Request.Content.ReadAsStringAsync().Result;
var snsMessage = Amazon.SimpleNotificationService.Util.Message.ParseMessage(jsonData);

//verify the signaure using AWS method
if(!snsMessage.IsMessageSignatureValid())
    throw new Exception("Invalid signature");

if(snsMessage.Type == Amazon.SimpleNotificationService.Util.Message.MESSAGE_TYPE_SUBSCRIPTION_CONFIRMATION)
{
    var subscribeUrl = snsMessage.SubscribeURL;
    var webClient = new WebClient();
    webClient.DownloadString(subscribeUrl);
    return "Successfully subscribed to: " + subscribeUrl;
}

2

我不知道最近这个问题是否有所改变,但我发现 AWS SNS 现在提供了一种非常简单的订阅方法,不需要提取 URL 或使用 RESTSharp 来构建请求......以下是简化后的 WebApi POST 方法:

    [HttpPost]
    public HttpResponseMessage Post(string id = "")
    {
        try
        {
            var jsonData = Request.Content.ReadAsStringAsync().Result;
            var sm = Amazon.SimpleNotificationService.Util.Message.ParseMessage(jsonData);

            if (sm.IsSubscriptionType)
            {
                sm.SubscribeToTopic(); // CONFIRM THE SUBSCRIPTION
            }
            if (sm.IsNotificationType) // PROCESS NOTIFICATIONS
            {
                //read for topic: sm.TopicArn
                //read for data: dynamic json = JObject.Parse(sm.MessageText);
                //extract value: var s3OrigUrlSnippet = json.input.key.Value as string;
            }

            //do stuff
            return Request.CreateResponse(HttpStatusCode.OK, new { });
        }
        catch (Exception ex)
        {
            //LogIt.E(ex);
            return Request.CreateResponse(HttpStatusCode.InternalServerError, new { status = "unexpected error" });
        }
    }

1
虽然这是一篇旧帖子,但我还是想试一试。我正在尝试在Message类上使用SubscribeToTopic()方法,但由于某种原因它并不存在。我正在使用AWSSDK.SimpleNotificationService NuGet包,版本:3.3.3.23,但该方法并不存在。请问您使用了哪些NuGet包?提前告知:我正在使用.NET Core 2.2 :) - fatherOfWine

2

在 @Craig 上面的回答基础上(对我非常有帮助),以下是一个 ASP.NET MVC WebAPI 控制器,用于消费和自动订阅 SNS 主题。#WebHooksFTW

using RestSharp;
using System;
using System.Net;
using System.Net.Http;
using System.Reflection;
using System.Web.Http;
using System.Web.Http.Description;

namespace sb.web.Controllers.api {
  [System.Web.Mvc.HandleError]
  [AllowAnonymous]
  [ApiExplorerSettings(IgnoreApi = true)]
  public class SnsController : ApiController {
    private static string className = MethodBase.GetCurrentMethod().DeclaringType.Name;

    [HttpPost]
    public HttpResponseMessage Post(string id = "") {
      try {
        var jsonData = Request.Content.ReadAsStringAsync().Result;
        var sm = Amazon.SimpleNotificationService.Util.Message.ParseMessage(jsonData);
        //LogIt.D(jsonData);
        //LogIt.D(sm);

        if (!string.IsNullOrEmpty(sm.SubscribeURL)) {
          var uri = new Uri(sm.SubscribeURL);
          var baseUrl = uri.GetLeftPart(System.UriPartial.Authority);
          var resource = sm.SubscribeURL.Replace(baseUrl, "");
          var response = new RestClient {
            BaseUrl = new Uri(baseUrl),
          }.Execute(new RestRequest {
            Resource = resource,
            Method = Method.GET,
            RequestFormat = RestSharp.DataFormat.Xml
          });
          if (response.StatusCode != System.Net.HttpStatusCode.OK) {
            //LogIt.W(response.StatusCode);
          } else {
            //LogIt.I(response.Content);
          }
        }

        //read for topic: sm.TopicArn
        //read for data: dynamic json = JObject.Parse(sm.MessageText);
        //extract value: var s3OrigUrlSnippet = json.input.key.Value as string;

        //do stuff
        return Request.CreateResponse(HttpStatusCode.OK, new { });
      } catch (Exception ex) {
        //LogIt.E(ex);
        return Request.CreateResponse(HttpStatusCode.InternalServerError, new { status = "unexpected error" });
      }
    }
  }
}

你如何告诉SNS将流量发送到这个URL? - A X

-1
以下示例帮助我处理SNS。 它经过所有与主题一起工作的步骤。 在这种情况下,订阅请求是电子邮件地址,但可以更改为HTTP。 Pavel的SNS示例 文档

谢谢,但是那个例子没有包括通过http确认订阅,这正是我遇到困难的具体问题。 - Scott Anderson

-1

我最终使用所示代码使其正常工作。在开发服务器上,我遇到了捕获异常的问题,结果发现服务器的时间与SNS消息中的时间戳不匹配。

一旦服务器的时间被修复(顺便说一下,这是一个亚马逊服务器),确认就可以正常工作了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接