Hubs de notificação Azure Secure Push

Descrição Geral

O suporte de notificação push em Microsoft Azure permite-lhe aceder a uma infraestrutura push de fácil utilização, multiplataforma e dimensionada, o que simplifica consideravelmente a implementação de notificações push para aplicações de consumidores e empresas para plataformas móveis.

Devido a restrições regulamentares ou de segurança, por vezes, um pedido pode querer incluir algo na notificação que não pode ser transmitido através da infraestrutura padrão de notificação push. Este tutorial descreve como obter a mesma experiência enviando informações sensíveis através de uma ligação segura e autenticada entre o dispositivo do cliente e o backend da app.

A um nível elevado, o fluxo é o seguinte:

  1. A aplicação back-end:
    • As lojas protegem a carga útil na base de dados back-end.
    • Envia o ID desta notificação para o dispositivo (não é enviada nenhuma informação segura).
  2. A aplicação no dispositivo, ao receber a notificação:
    • O dispositivo contacta a parte de trás solicitando a carga útil segura.
    • A aplicação pode mostrar a carga útil como uma notificação no dispositivo.

É importante notar que no fluxo anterior (e neste tutorial), assumimos que o dispositivo armazena um token de autenticação no armazenamento local, após o registo do utilizador. Isto garante uma experiência perfeita, uma vez que o dispositivo pode recuperar a carga útil segura da notificação utilizando este token. Se a sua aplicação não armazenar fichas de autenticação no dispositivo, ou se estas fichas puderem ser expiradas, a aplicação do dispositivo, ao receber a notificação, deverá apresentar uma notificação genérica que o levou o utilizador a lançar a aplicação. A aplicação autentica então o utilizador e mostra a carga útil da notificação.

Este tutorial Secure Push mostra como enviar uma notificação push de forma segura. O tutorial baseia-se no tutorial de Notificação dos Utilizadores , pelo que deve completar primeiro os passos nesse tutorial.

Nota

Este tutorial pressupõe que criou e configura o seu centro de notificações como descrito no Enviar notificações push para aplicações iOS usando Azure Notification Hubs.

Projeto WebAPI

  1. No Visual Studio, abra o projeto AppBackend que criou no tutorial de Notifica users .

  2. Em Notificações.cs, substitua toda a classe notificações pelo seguinte código. Certifique-se de que substitui os espaços reservados pela sua cadeia de ligação (com acesso total) para o seu centro de notificação e o nome do hub. Pode obter estes valores a partir do portal do Azure. Este módulo representa agora as diferentes notificações seguras que serão enviadas. Numa implementação completa, as notificações serão armazenadas numa base de dados; para a simplicidade, neste caso os armazenamos na memória.

     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. Em NotificationsController.cs, substitua o código dentro da definição da classe NotificationsController pelo seguinte código. Este componente implementa uma forma de o dispositivo recuperar a notificação de forma segura, e também fornece uma forma (para efeitos deste tutorial) de desencadear um empurrão seguro para os seus dispositivos. Note que ao enviar a notificação para o centro de notificação, apenas enviamos uma notificação em bruto com o ID da notificação (e nenhuma mensagem real):

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

Note que o Post método agora não envia uma notificação de torrada. Envia uma notificação em bruto que contém apenas o ID de notificação, e não qualquer conteúdo sensível. Além disso, certifique-se de comentar a operação de envio para as plataformas para as quais não tem credenciais configuradas no seu centro de notificações, uma vez que resultarão em erros.

  1. Agora vamos re-implantar esta aplicação para um Website Azure de forma a torná-la acessível a partir de todos os dispositivos. Clique com o botão direito do rato no projeto AppBackend e selecione Publicar.
  2. Selecione o Website Azure como o seu alvo de publicação. Faça sedida com a sua conta Azure e selecione um Website existente ou novo, e tome nota da propriedade URL de destino no separador 'Ligação '. Vamos referir-nos a este URL como o seu ponto final de backend mais tarde neste tutorial. Clique em Publish (Publicar).

Modifique o projeto iOS

Agora que modificou a sua aplicação para enviar apenas o ID de uma notificação, tem de alterar a sua aplicação iOS para lidar com essa notificação e voltar a ligar para recuperar a mensagem segura a ser exibida.

Para atingir este objetivo, temos de escrever a lógica para recuperar o conteúdo seguro a partir do back-end da app.

  1. Em AppDelegate.m, certifique-se de que a aplicação regista as notificações silenciosas para que processe o ID de notificação enviado a partir do backend. Adicione a opção UIRemoteNotificationTypeNewsstandContentAvailability em didFinishLaunchingWithOptions:

    [[UIApplication sharedApplication] registerForRemoteNotificationTypes: UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeNewsstandContentAvailability];
    
  2. Na sua AppDelegate.m secção de implementação no topo com a seguinte declaração:

    @interface AppDelegate ()
    - (void) retrieveSecurePayloadWithId:(int)payloadId completion: (void(^)(NSString*, NSError*)) completion;
    @end
    
  3. Em seguida, adicione na secção de implementação o seguinte código, substituindo o espaço reservado pelo ponto final {back-end endpoint} para o seu back-end obtido anteriormente:

    NSString *const GetNotificationEndpoint = @"{back-end endpoint}/api/notifications";
    
    - (void) retrieveSecurePayloadWithId:(int)payloadId completion: (void(^)(NSString*, NSError*)) completion;
    {
        // check if authenticated
        ANHViewController* rvc = (ANHViewController*) self.window.rootViewController;
        NSString* authenticationHeader = rvc.registerClient.authenticationHeader;
        if (!authenticationHeader) return;
    
        NSURLSession* session = [NSURLSession
                                    sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]
                                    delegate:nil
                                    delegateQueue:nil];
    
        NSURL* requestURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@/%d", GetNotificationEndpoint, payloadId]];
        NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:requestURL];
        [request setHTTPMethod:@"GET"];
        NSString* authorizationHeaderValue = [NSString stringWithFormat:@"Basic %@", authenticationHeader];
        [request setValue:authorizationHeaderValue forHTTPHeaderField:@"Authorization"];
    
        NSURLSessionDataTask* dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
            NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*) response;
            if (!error && httpResponse.statusCode == 200)
            {
                NSLog(@"Received secure payload: %@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
    
                NSMutableDictionary *json = [NSJSONSerialization JSONObjectWithData:data options: NSJSONReadingMutableContainers error: &error];
    
                completion([json objectForKey:@"Payload"], nil);
            }
            else
            {
                NSLog(@"Error status: %ld, request: %@", (long)httpResponse.statusCode, error);
                if (error)
                    completion(nil, error);
                else {
                    completion(nil, [NSError errorWithDomain:@"APICall" code:httpResponse.statusCode userInfo:nil]);
                }
            }
        }];
        [dataTask resume];
    }
    

    Este método chama a sua aplicação de back-end para recuperar o conteúdo da notificação usando as credenciais armazenadas nas preferências partilhadas.

  4. Agora, manuseie a notificação recebida e utilize o método acima para recuperar o conteúdo para visualizar. Em primeiro lugar, permita que a sua aplicação iOS seja executada em segundo plano ao receber uma notificação push. No XCode, selecione o seu projeto de aplicação no painel esquerdo e, em seguida, clique no seu alvo principal de aplicação na secção Alvos a partir do painel central.

  5. Em seguida, clique no separador Capabilites na parte superior do painel central e verifique a caixa de Notificações Remotas .

    Screenshot do XCode, com o projeto da aplicação selecionado e o separador Capabilities aberto. A caixa de verificação de notificações remotas é selecionada.

  6. Adicione AppDelegate.m o seguinte método para lidar com notificações push:

    -(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
    {
        NSLog(@"%@", userInfo);
    
        [self retrieveSecurePayloadWithId:[[userInfo objectForKey:@"secureId"] intValue] completion:^(NSString * payload, NSError *error) {
            if (!error) {
                // show local notification
                UILocalNotification* localNotification = [[UILocalNotification alloc] init];
                localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:0];
                localNotification.alertBody = payload;
                localNotification.timeZone = [NSTimeZone defaultTimeZone];
                [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
    
                completionHandler(UIBackgroundFetchResultNewData);
            } else {
                completionHandler(UIBackgroundFetchResultFailed);
            }
        }];
    
    }
    

    Note que é preferível lidar com os casos de propriedade ou rejeição de cabeçalho de autenticação em falta ou rejeição pelo back-end. O tratamento específico destes casos depende principalmente da experiência do utilizador-alvo. Uma opção é apresentar uma notificação com um pedido genérico para que o utilizador autentica para recuperar a notificação real.

Executar a Aplicação

Para executar a aplicação, faça o seguinte:

  1. No XCode, execute a aplicação num dispositivo físico iOS (as notificações push não funcionarão no simulador).
  2. Na aplicação iOS UI, insira um nome de utilizador e senha. Estes podem ser qualquer corda, mas devem ter o mesmo valor.
  3. Na aplicação iOS UI, clique em Iniciarões de Sessão. Em seguida, clique em Enviar o empurrão. Deverá ver a notificação segura a ser exibida no seu centro de notificação.