Безопасная отправка push-уведомлений из Центров уведомлений Azure

Обзор

Поддержка push-уведомлений в Microsoft Azure позволяет получить доступ к простой, многоплатформенной и масштабируемой инфраструктуре для отправки push-уведомлений. Она значительно упрощает реализацию push-уведомлений как для объекта-получателя, так и для корпоративных приложений для мобильных платформ.

Из-за ограничений, связанных с правовыми нормами или обеспечением безопасности, иногда в уведомлении могут присутствовать данные, которые нельзя передать через стандартную инфраструктуру push-уведомлений. В этом учебнике рассказывается о том, как реализовать этот принцип при отправке важной информации через защищенное соединение с проверкой подлинности, установленное между устройством клиента и серверной частью приложения.

На высоком уровне поток можно представить следующим образом.

  1. Серверная часть приложения:
    • Сохраняет полезную нагрузку в базе данных серверной части.
    • Отправляет идентификатор этого уведомления устройству (защищаемые сведения не передаются).
  2. Приложение на устройстве при получении уведомления:
    • Устройство связывается с серверной частью и запрашивает полезную нагрузку.
    • Приложение может показывать полезную нагрузку в виде уведомления на устройстве.

Стоит отметить: в предыдущем потоке (и в этом учебнике) мы предположили, что устройство сохраняет маркер проверки подлинности в локальном хранилище после входа пользователя. Таким образом обеспечивается удобство работы, так как с помощью этого маркера устройство способно получать безопасные полезные данные уведомлений. Если приложение не сохраняет маркеры проверки подлинности на устройстве, или если истек срок действия маркеров, приложение устройства, после получения уведомления, должно отобразить общее уведомление, предлагая пользователю запустить приложение. Затем приложение выполняет проверку подлинности пользователя и отображает полезную нагрузку уведомления.

В этом учебнике показано, как безопасно отправить push-уведомление. Данный учебник является продолжением другого учебника под названием Уведомление пользователей, поэтому необходимо сначала выполнить шаги в указанном учебнике.

Примечание

В этом учебнике подразумевается, что вы создали и настроили центр уведомлений в соответствии с описанием в руководстве по отправке уведомлений в приложения универсальной платформы Windows. Кроме того, обратите внимание, что для Windows Phone 8.1 требуются учетные данные Windows (не Windows Phone) и что фоновые задачи не работают на Windows Phone 8.0 и в Silverlight 8.1. При работе в приложениями из Магазина Windows уведомления можно получать через фоновую задачу только в том случае, если включен экран блокировки приложения (установите флажок в Appmanifest).

Проект веб-интерфейса API

  1. В Visual Studio откройте проект AppBackend , созданный в учебнике Уведомление пользователей .

  2. В файле замените Notifications.cs целый класс Уведомления на следующий код. Убедитесь, что заменили заполнители на строку подключения (с полным доступом) для центра уведомлений и имени центра. Эти значения можно получить на портале Azure. В этом модуле теперь представлены разные уведомления безопасности, которые будут отправлены. При полной реализации уведомления будут сохранены в базе данных; для упрощения в этом случае мы сохраняем их память.

     public class Notification
     {
         public int Id { get; set; }
         public string Payload { get; set; }
         public bool Read { get; set; }
     }
    
     public class Notifications
     {
         public static Notifications Instance = new Notifications();
    
         private List<Notification> notifications = new List<Notification>();
    
         public NotificationHubClient Hub { get; set; }
    
         private Notifications() {
             Hub = NotificationHubClient.CreateClientFromConnectionString("{conn string with full access}",     "{hub name}");
         }
    
         public Notification CreateNotification(string payload)
         {
             var notification = new Notification() {
             Id = notifications.Count,
             Payload = payload,
             Read = false
             };
    
             notifications.Add(notification);
    
             return notification;
         }
    
         public Notification ReadNotification(int id)
         {
             return notifications.ElementAt(id);
         }
     }
    
  3. Замените в файле NotificationsController.cs код в определении класса NotificationsController на следующий. Этот компонент реализует способ безопасного получения уведомления устройством, а также способ (в обучающих целях) активации безопасного push-уведомления для устройств. Обратите внимание, что при отправке уведомления в центр уведомлений мы отправляем только необработанное уведомление с идентификатором уведомления (без фактического сообщения):

     public NotificationsController()
     {
         Notifications.Instance.CreateNotification("This is a secure notification!");
     }
    
     // GET api/notifications/id
     public Notification Get(int id)
     {
         return Notifications.Instance.ReadNotification(id);
     }
    
     public async Task<HttpResponseMessage> Post()
     {
         var secureNotificationInTheBackend = Notifications.Instance.CreateNotification("Secure confirmation.");
         var usernameTag = "username:" + HttpContext.Current.User.Identity.Name;
    
         // windows
         var rawNotificationToBeSent = new Microsoft.Azure.NotificationHubs.WindowsNotification(secureNotificationInTheBackend.Id.ToString(),
                         new Dictionary<string, string> {
                             {"X-WNS-Type", "wns/raw"}
                         });
         await Notifications.Instance.Hub.SendNotificationAsync(rawNotificationToBeSent, usernameTag);
    
         // apns
         await Notifications.Instance.Hub.SendAppleNativeNotificationAsync("{\"aps\": {\"content-available\": 1}, \"secureId\": \"" + secureNotificationInTheBackend.Id.ToString() + "\"}", usernameTag);
    
         // gcm
         await Notifications.Instance.Hub.SendGcmNativeNotificationAsync("{\"data\": {\"secureId\": \"" + secureNotificationInTheBackend.Id.ToString() + "\"}}", usernameTag);
    
         return Request.CreateResponse(HttpStatusCode.OK);
     }
    

Обратите внимание, что теперь метод Post не отправляет всплывающее уведомление. Он отправляет необработанное уведомление, которое содержит только идентификатор уведомления без конфиденциального содержимого. Также убедитесь, что закомментировали операцию отправки для платформ, для которых вы не настроили учетные данные в концентраторе уведомлений, поскольку они приведут к ошибкам.

  1. После этого повторно развернем это приложение на веб-сайте Azure, чтобы сделать его доступным для всех устройств. Щелкните правой кнопкой мыши проект AppBackend и нажмите кнопку Опубликовать.
  2. Выберите в качестве цели публикации веб-сайт Azure. Выполните вход с помощью учетной записи Azure, выберите существующий или новый веб-сайт и запишите значение свойства URL-адрес назначения на вкладке Подключение. Далее в учебнике этот URL-адрес будет называться конечной точкой серверной части. Нажмите кнопку Опубликовать.

Изменение проекта для Windows Phone

  1. В проекте NotifyUserWindowsPhone добавьте следующий код в App.xaml.cs, чтобы зарегистрировать фоновую задачу push-уведомления. В конце метода OnLaunched() добавьте следующую строку кода:

    RegisterBackgroundTask();
    
  2. Находясь в App.xaml.cs, добавьте следующий код сразу после метода OnLaunched() :

    private async void RegisterBackgroundTask()
    {
        if (!Windows.ApplicationModel.Background.BackgroundTaskRegistration.AllTasks.Any(i => i.Value.Name == "PushBackgroundTask"))
        {
            var result = await BackgroundExecutionManager.RequestAccessAsync();
            var builder = new BackgroundTaskBuilder();
    
            builder.Name = "PushBackgroundTask";
            builder.TaskEntryPoint = typeof(PushBackgroundComponent.PushBackgroundTask).FullName;
            builder.SetTrigger(new Windows.ApplicationModel.Background.PushNotificationTrigger());
            BackgroundTaskRegistration task = builder.Register();
        }
    }
    
  3. Добавьте в начало файла App.xaml.cs следующие операторы using :

    using Windows.Networking.PushNotifications;
    using Windows.ApplicationModel.Background;
    
  4. В меню Файл Visual Studio выберите Сохранить все.

Создание фонового компонента push-уведомления

Следующий шаг заключается в создании фонового компонента push-уведомления.

  1. В обозревателе решений щелкните правой кнопкой мыши узел верхнего уровня решения (в данном случае — Solution SecurePush), а затем нажмите кнопку Добавить, после чего щелкните Создать проект.

  2. Разверните пункт Приложения Магазина, затем щелкните Приложения Windows Phone и выберите Компонент среды выполнения Windows (Windows Phone). Присвойте проекту имя PushBackgroundComponent, а затем нажмите кнопку ОК, чтобы создать проект.

    Снимок экрана: диалоговое окно

  3. В обозревателе решений щелкните правой кнопкой мыши проект PushBackgroundComponent (Windows Phone 8.1), а затем щелкните Добавить и выберите Класс. Присвойте новому классу имя PushBackgroundTask.cs. Щелкните кнопку Добавить , чтобы создать класс.

  4. Замените все содержимое определения пространства имен PushBackgroundComponent следующим кодом, заменив заполнитель {back-end endpoint} конечной точкой серверной части, полученной при развертывании серверной части:

    public sealed class Notification
        {
            public int Id { get; set; }
            public string Payload { get; set; }
            public bool Read { get; set; }
        }
    
        public sealed class PushBackgroundTask : IBackgroundTask
        {
            private string GET_URL = "{back-end endpoint}/api/notifications/";
    
            async void IBackgroundTask.Run(IBackgroundTaskInstance taskInstance)
            {
                // Store the content received from the notification so it can be retrieved from the UI.
                RawNotification raw = (RawNotification)taskInstance.TriggerDetails;
                var notificationId = raw.Content;
    
                // retrieve content
                BackgroundTaskDeferral deferral = taskInstance.GetDeferral();
                var httpClient = new HttpClient();
                var settings = ApplicationData.Current.LocalSettings.Values;
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", (string)settings["AuthenticationToken"]);
    
                var notificationString = await httpClient.GetStringAsync(GET_URL + notificationId);
    
                var notification = JsonConvert.DeserializeObject<Notification>(notificationString);
    
                ShowToast(notification);
    
                deferral.Complete();
            }
    
            private void ShowToast(Notification notification)
            {
                ToastTemplateType toastTemplate = ToastTemplateType.ToastText01;
                XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(toastTemplate);
                XmlNodeList toastTextElements = toastXml.GetElementsByTagName("text");
                toastTextElements[0].AppendChild(toastXml.CreateTextNode(notification.Payload));
                ToastNotification toast = new ToastNotification(toastXml);
                ToastNotificationManager.CreateToastNotifier().Show(toast);
            }
        }
    
  5. В обозревателе решений щелкните правой кнопкой мыши проект PushBackgroundComponent (Windows Phone 8.1), а затем щелкните Управление пакетами NuGet.

  6. В левой части окна выберите В сети.

  7. В текстовом поле Поиск введите Клиент HTTP.

  8. В списке результатов выберите Клиентские библиотеки Microsoft HTTP и нажмите Установить. Выполните установку.

  9. Вернитесь к полю NuGet Поиск и введите Json.net. Установите пакет Json.NET , затем закройте окно диспетчера пакетов NuGet.

  10. Добавьте следующие инструкции using в начало файла PushBackgroundTask.cs.

    using Windows.ApplicationModel.Background;
    using Windows.Networking.PushNotifications;
    using System.Net.Http;
    using Windows.Storage;
    using System.Net.Http.Headers;
    using Newtonsoft.Json;
    using Windows.UI.Notifications;
    using Windows.Data.Xml.Dom;
    
  11. В Обозревателе решений в проекте NotifyUserWindowsPhone (Windows Phone 8.1) щелкните правой кнопкой мыши Ссылки, а затем выберите команду Добавить ссылку… . В диалоговом окне "Диспетчер ссылок" установите флажок рядом с пунктом PushBackgroundComponent, а затем нажмите кнопку ОК.

  12. В обозревателе решений дважды щелкните Package.appxmanifest в проекте NotifyUserWindowsPhone (Windows Phone 8.1). В поле Уведомления установите для параметра Всплывающие уведомления значение Да.

    Снимок экрана: окно

  13. Находясь в Package.appxmanifest, откройте меню Объявления вверху. В раскрывающемся списке Доступные объявления щелкните Фоновые задачи и затем нажмите кнопку Добавить.

  14. В Package.appxmanifest в разделе Свойства включите параметр Push-уведомление.

  15. В Package.appxmanifest в области Параметры приложения введите PushBackgroundComponent.PushBackgroundTask в поле Точка входа.

    Снимок экрана: окно

  16. В меню Файл выберите Сохранить все.

Выполнение приложения

Для запуска приложения выполните следующие действия:

  1. В Visual Studio запустите приложение веб-API AppBackend . Отобразится веб-страница ASP.NET.
  2. В Visual Studio запустите приложение NotifyUserWindowsPhone (Windows Phone 8.1) для Windows Phone. Эмулятор Windows Phone запустится и автоматически загрузит приложение.
  3. В пользовательском интерфейсе приложения NotifyUserWindowsPhone введите имя пользователя и пароль. Это могут быть любые совпадающие строки.
  4. В пользовательском интерфейсе приложения NotifyUserWindowsPhone щелкните Log in and register (Вход и регистрация). Затем нажмите Отправить push-уведомление.