Azure Notification Hubs Secure Push

Overzicht

Met ondersteuning voor pushmeldingen in Microsoft Azure krijgt u toegang tot een gebruiksvriendelijke, uitgebreide push-infrastructuur met meerdere platforms, die de implementatie van pushmeldingen voor zowel consumenten- als bedrijfstoepassingen voor mobiele platforms aanzienlijk vereenvoudigt.

Vanwege wettelijke of beveiligingsbeperkingen wil een toepassing soms iets in de melding opnemen dat niet kan worden verzonden via de standaardinfrastructuur voor pushmeldingen. In deze zelfstudie wordt beschreven hoe u dezelfde ervaring kunt bereiken door gevoelige informatie te verzenden via een beveiligde, geverifieerde verbinding tussen het clientapparaat en de back-end van de app.

Op hoog niveau is de stroom als volgt:

  1. De back-end van de app:
    • Slaat een beveiligde nettolading op in de back-enddatabase.
    • Hiermee wordt de id van deze melding naar het apparaat verzonden (er wordt geen beveiligde informatie verzonden).
  2. De app op het apparaat, wanneer de melding wordt ontvangen:
    • Het apparaat maakt contact met de back-end en vraagt de beveiligde nettolading aan.
    • De app kan de nettolading weergeven als een melding op het apparaat.

Het is belangrijk te weten dat we in de voorgaande stroom (en in deze zelfstudie) ervan uitgaan dat het apparaat een verificatietoken opslaat in de lokale opslag, nadat de gebruiker zich heeft aangemeld. Dit garandeert een naadloze ervaring, omdat het apparaat de beveiligde nettolading van de melding kan ophalen met behulp van dit token. Als in uw toepassing geen verificatietokens op het apparaat worden opgeslagen of als deze tokens kunnen worden verlopen, moet de apparaat-app na ontvangst van de melding een algemene melding weergeven waarin de gebruiker wordt gevraagd de app te starten. De app verifieert vervolgens de gebruiker en toont de nettolading van de melding.

In deze zelfstudie over beveiligd pushen ziet u hoe u veilig een pushmelding verzendt. De zelfstudie bouwt voort op de zelfstudie Gebruikers waarschuwen , dus u moet eerst de stappen in die zelfstudie voltooien.

Notitie

In deze zelfstudie wordt ervan uitgegaan dat u uw Notification Hub hebt gemaakt en geconfigureerd, zoals beschreven in Pushmeldingen verzenden naar iOS-apps met behulp van Azure Notification Hubs.

WebAPI-project

  1. Open in Visual Studio het project AppBackend dat u hebt gemaakt in de zelfstudie Gebruikers waarschuwen .

  2. Vervang in Notifications.cs de volledige klasse Notifications door de volgende code. Zorg ervoor dat u de tijdelijke aanduidingen vervangt door uw connection string (met volledige toegang) voor uw Notification Hub en de naam van de hub. U kunt deze waarden ophalen uit de Azure Portal. Deze module vertegenwoordigt nu de verschillende beveiligde meldingen die worden verzonden. In een volledige implementatie worden de meldingen opgeslagen in een database; Voor het gemak slaan we ze in dit geval op in het geheugen.

     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. Vervang in NotificationsController.cs de code in de klassedefinitie NotificationsController door de volgende code. Dit onderdeel implementeert een manier voor het apparaat om de melding veilig op te halen en biedt ook een manier (voor de doeleinden van deze zelfstudie) om een beveiligde push naar uw apparaten te activeren. Houd er rekening mee dat we bij het verzenden van de melding naar de Notification Hub alleen een onbewerkte melding verzenden met de id van de melding (en geen echt bericht):

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

Houd er rekening mee dat de Post methode nu geen pop-upmelding verzendt. Er wordt een onbewerkte melding verzonden die alleen de meldings-id bevat en geen gevoelige inhoud. Zorg er ook voor dat u opmerkingen maakt bij de verzendbewerking voor de platforms waarvoor u geen referenties hebt geconfigureerd op uw Notification Hub, omdat deze fouten zullen veroorzaken.

  1. Nu gaan we deze app opnieuw implementeren op een Azure-website om deze toegankelijk te maken vanaf alle apparaten. Klik met de rechtermuisknop op het project AppBackend en selecteer Publiceren.
  2. Selecteer Azure-website als publicatiedoel. Meld u aan met uw Azure-account, selecteer een bestaande of nieuwe website en noteer de eigenschap bestemmings-URL op het tabblad Verbinding . Verderop in deze zelfstudie wordt naar deze URL verwezen als uw back-endeindpunt . Klik op Publish.

Het iOS-project wijzigen

Nu u de back-end van uw app hebt aangepast om alleen de id van een melding te verzenden, moet u uw iOS-app wijzigen om die melding af te handelen en uw back-end terugbellen om het beveiligde bericht op te halen dat moet worden weergegeven.

Om dit doel te bereiken, moeten we de logica schrijven om de beveiligde inhoud op te halen uit de back-end van de app.

  1. Zorg er in AppDelegate.mvoor dat de app zich registreert voor meldingen op de achtergrond, zodat de meldings-id wordt verwerkt die vanuit de back-end is verzonden. Voeg de UIRemoteNotificationTypeNewsstandContentAvailability optie toe in didFinishLaunchingWithOptions:

    [[UIApplication sharedApplication] registerForRemoteNotificationTypes: UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeNewsstandContentAvailability];
    
  2. AppDelegate.m Voeg bovenaan een implementatiesectie toe met de volgende declaratie:

    @interface AppDelegate ()
    - (void) retrieveSecurePayloadWithId:(int)payloadId completion: (void(^)(NSString*, NSError*)) completion;
    @end
    
  3. Voeg vervolgens in de implementatiesectie de volgende code toe, waarbij u de tijdelijke aanduiding {back-end endpoint} vervangt door het eindpunt voor uw back-end die u eerder hebt verkregen:

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

    Met deze methode wordt de back-end van uw app aangeroepen om de meldingsinhoud op te halen met behulp van de referenties die zijn opgeslagen in de gedeelde voorkeuren.

  4. Verwerk nu de binnenkomende melding en gebruik de bovenstaande methode om de weer te geven inhoud op te halen. Schakel eerst in dat uw iOS-app op de achtergrond wordt uitgevoerd wanneer u een pushmelding ontvangt. Selecteer in XCode uw app-project in het linkerdeelvenster en klik vervolgens op uw belangrijkste app-doel in de sectie Doelen in het centrale deelvenster.

  5. Klik vervolgens op het tabblad Mogelijkheden bovenaan het centrale deelvenster en schakel het selectievakje Externe meldingen in.

    Schermopname van XCode, met het app-project geselecteerd en het tabblad Mogelijkheden geopend. Het selectievakje Externe meldingen is ingeschakeld.

  6. Voeg AppDelegate.m de volgende methode toe om pushmeldingen af te handelen:

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

    Houd er rekening mee dat het de voorkeur verdient om gevallen van ontbrekende verificatieheadereigenschap of afwijzing door de back-end af te handelen. De specifieke afhandeling van deze gevallen is voornamelijk afhankelijk van de gebruikerservaring van uw doel. Een optie is om een melding weer te geven met een algemene prompt voor de gebruiker om te verifiëren om de werkelijke melding op te halen.

De toepassing uitvoeren

Ga als volgt te werk om de toepassing uit te voeren:

  1. Voer in XCode de app uit op een fysiek iOS-apparaat (pushmeldingen werken niet in de simulator).
  2. Voer in de gebruikersinterface van de iOS-app een gebruikersnaam en wachtwoord in. Dit kan elke tekenreeks zijn, maar ze moeten dezelfde waarde hebben.
  3. Klik in de gebruikersinterface van de iOS-app op Aanmelden. Klik vervolgens op Push verzenden. Als het goed is, wordt de beveiligde melding weergegeven in het meldingencentrum.