Säker push-överföring i Azure Notification Hubs

Översikt

Med push-meddelandestöd i Microsoft Azure kan du komma åt en lätthanterad och utskalad push-infrastruktur med flera plattformar, vilket avsevärt förenklar implementeringen av push-meddelanden för både konsument- och företagsprogram för mobila plattformar.

På grund av regel- eller säkerhetsbegränsningar kan ett program ibland vilja inkludera något i meddelandet som inte kan överföras via standardinfrastrukturen för push-meddelanden. Den här självstudien beskriver hur du uppnår samma upplevelse genom att skicka känslig information via en säker, autentiserad anslutning mellan klientenheten och appens serverdel.

På en hög nivå är flödet följande:

  1. Appens serverdel:
    • Lagrar säker nyttolast i serverdelsdatabasen.
    • Skickar ID:t för det här meddelandet till enheten (ingen säker information skickas).
  2. Appen på enheten när du tar emot meddelandet:
    • Enheten kontaktar serverdelen och begär den säkra nyttolasten.
    • Appen kan visa nyttolasten som ett meddelande på enheten.

Observera att i föregående flöde (och i den här självstudien) förutsätter vi att enheten lagrar en autentiseringstoken i lokal lagring efter att användaren har loggat in. Detta garanterar en sömlös upplevelse eftersom enheten kan hämta meddelandets säkra nyttolast med den här token. Om ditt program inte lagrar autentiseringstoken på enheten, eller om dessa token kan upphöra att gälla, bör enhetsappen, när den tar emot meddelandet, visa ett allmänt meddelande som uppmanar användaren att starta appen. Appen autentiserar sedan användaren och visar aviseringsnyttolasten.

Den här självstudien om säker push visar hur du skickar ett push-meddelande på ett säkert sätt. Självstudien bygger på självstudien Meddela användare , så du bör slutföra stegen i självstudien först.

Anteckning

Den här självstudien förutsätter att du har skapat och konfigurerat din meddelandehubb enligt beskrivningen i Skicka push-meddelanden till iOS-appar med Azure Notification Hubs.

WebAPI-projekt

  1. I Visual Studio öppnar du det AppBackend-projekt som du skapade i självstudien Meddela användare .

  2. I Notifications.cs ersätter du hela klassen Meddelanden med följande kod. Se till att ersätta platshållarna med anslutningssträngen (med fullständig åtkomst) för meddelandehubben och hubbens namn. Du kan hämta dessa värden från Azure Portal. Den här modulen representerar nu de olika säkra meddelanden som ska skickas. I en fullständig implementering lagras meddelandena i en databas. för enkelhetens skull lagrar vi dem i minnet.

     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. I NotificationsController.cs ersätter du koden i klassen NotificationsController med följande kod. Den här komponenten implementerar ett sätt för enheten att hämta meddelandet på ett säkert sätt och tillhandahåller även ett sätt (i den här självstudiekursen) att utlösa en säker push-överföring till dina enheter. Observera att när vi skickar meddelandet till meddelandehubben skickar vi bara ett råmeddelande med ID:t för meddelandet (och inget faktiskt meddelande):

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

Observera att Post metoden nu inte skickar ett popup-meddelande. Den skickar ett råmeddelande som endast innehåller meddelande-ID:t och inte känsligt innehåll. Se också till att kommentera sändningsåtgärden för de plattformar som du inte har autentiseringsuppgifter konfigurerade för på meddelandehubben, eftersom de resulterar i fel.

  1. Nu ska vi distribuera om den här appen till en Azure-webbplats för att göra den tillgänglig från alla enheter. Högerklicka på AppBackend-projektet och välj Publicera.
  2. Välj Azure-webbplats som publiceringsmål. Logga in med ditt Azure-konto och välj en befintlig eller ny webbplats och anteckna mål-URL-egenskapen på fliken Anslutning . Vi refererar till den här URL:en som din serverdelsslutpunkt senare i den här självstudien. Klicka på Publicera.

Ändra iOS-projektet

Nu när du har ändrat appens serverdel så att den bara skickar ID :t för ett meddelande måste du ändra din iOS-app för att hantera det meddelandet och anropa serverdelen för att hämta det säkra meddelandet som ska visas.

För att uppnå det här målet måste vi skriva logiken för att hämta det säkra innehållet från appens serverdel.

  1. I AppDelegate.mkontrollerar du att appen registreras för tysta meddelanden så att den bearbetar meddelande-ID:t som skickas från serverdelen. UIRemoteNotificationTypeNewsstandContentAvailability Lägg till alternativet i didFinishLaunchingWithOptions:

    [[UIApplication sharedApplication] registerForRemoteNotificationTypes: UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeNewsstandContentAvailability];
    
  2. AppDelegate.m Lägg till ett implementeringsavsnitt högst upp med följande deklaration:

    @interface AppDelegate ()
    - (void) retrieveSecurePayloadWithId:(int)payloadId completion: (void(^)(NSString*, NSError*)) completion;
    @end
    
  3. Lägg sedan till följande kod i implementeringsavsnittet och ersätt platshållaren {back-end endpoint} med slutpunkten för serverdelen som du fick tidigare:

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

    Den här metoden anropar appens serverdel för att hämta meddelandeinnehållet med de autentiseringsuppgifter som lagras i de delade inställningarna.

  4. Hantera nu det inkommande meddelandet och använd metoden ovan för att hämta innehållet som ska visas. Börja med att aktivera iOS-appen så att den körs i bakgrunden när du tar emot ett push-meddelande. I XCode väljer du ditt appprojekt på den vänstra panelen och klickar sedan på huvudappmålet i avsnittet Mål i det centrala fönstret.

  5. Klicka sedan på fliken Funktioner överst i det centrala fönstret och markera rutan Fjärrmeddelanden .

    Skärmbild av XCode med appprojektet valt och fliken Funktioner öppen. Kryssrutan Fjärrmeddelanden är markerad.

  6. Lägg AppDelegate.m till följande metod för att hantera push-meddelanden:

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

    Observera att det är bättre att hantera fall där autentiseringshuvudegenskap saknas eller avvisas av serverdelen. Den specifika hanteringen av dessa fall beror främst på målanvändarupplevelsen. Ett alternativ är att visa ett meddelande med en allmän uppmaning till användaren att autentisera för att hämta det faktiska meddelandet.

Kör programmet

Kör programmet genom att göra följande:

  1. I XCode kör du appen på en fysisk iOS-enhet (push-meddelanden fungerar inte i simulatorn).
  2. I användargränssnittet för iOS-appen anger du ett användarnamn och lösenord. Dessa kan vara valfri sträng, men de måste ha samma värde.
  3. I användargränssnittet för iOS-appen klickar du på Logga in. Klicka sedan på Skicka push. Du bör se att det säkra meddelandet visas i meddelandecentret.