none
Apple APNS WebRequest RRS feed

  • Frage

  • Hallo,

    wir haben mittlerweile Google und Windows Push mittels WebReqest hinbekommen, jedoch an Apple APNS beißen wir uns die Zähne aus, da es dazu nur veraltete, für uns nicht passende oder fehlerhafte Beispiele gibt. Die Apple Dokumentation wirft wie fast alle ohne konkrete Beispiele mehr Fragen als Antworten auf. Ziel ist ein WebRequest, der über ein Zertifikat läuft. Zertifikat und sämtlichen anderen Krams haben wir alles. 

    Soweit bin ich gekommen, aber wie sieht das Teil weiter bzw. komplett aus:

    Ich bin sicher, da fehlen einige Header Einträge oder Konfigurationsdaten und ob das Zertifikat richtig eingebunden ist weiß ich auch nicht.

    private EventLog eventLog;
            private X509Certificate2 serverCertificate;
    
            public ApplePusher(EventLog eventLog)
            { 
                this.eventLog = eventLog;
                serverCertificate = new X509Certificate2(String.Format("{0}TicketPusher-Sandbox.p12", AppDomain.CurrentDomain.BaseDirectory));
            }
    
            public void SendNotification(string deviceToken, string notification)
            {
                byte[] payloadBytes = Encoding.UTF8.GetBytes("{\"aps\":{\"alert\":\"" + notification + "\"}}");
                try
                {
                    HttpWebRequest request = HttpWebRequest.Create("api.development.push.apple.com:443") as HttpWebRequest;
                    request.ClientCertificates.Add(serverCertificate);
                    request.Method = "POST";
                    request.Headers.Add("path:/3/device/" + deviceToken);
                    using (Stream requestStream = request.GetRequestStream()) requestStream.Write(payloadBytes, 0, payloadBytes.Length);
                }
                catch (Exception ex)
                {
                    eventLog.WriteEntry(ex.Message);
                }
            }

    Donnerstag, 13. April 2017 15:10

Antworten

  • using System;
    using System.Diagnostics;
    using System.IO;
    using System.Linq;
    using System.Net.Security;
    using System.Net.Sockets;
    using System.Security.Authentication;
    using System.Security.Cryptography.X509Certificates;
    
    namespace Pusher
    {
        public class ApplePusher
        {
            private EventLog eventLog;
    
            public ApplePusher(EventLog eventLog)
            {
                this.eventLog = eventLog;
            }
    
            public void SendNotification(string deviceToken, string notification)
            {
                //Port des Apple Pushbenachrichtigungsdienstes (APNS)
                int port = 2195;
                //Hostname für Entwicklungsbetrieb
                string hostname = "gateway.sandbox.push.apple.com";
                //Hostname für Produktionsbetrieb
                //string hostname = "gateway.push.apple.com";
                //Pfad zur Zertifikatsdatei
                string certificatePath = @"apns-certificate.p12";
                //Erzeugung eines neuen Clientzertifikates aus der Zertifikatsdatei
                X509Certificate2 clientCertificate = new X509Certificate2(File.ReadAllBytes(certificatePath), "");
                //Hinzufügen des Zertifikates zu einer Zertifikatssammlung
                X509Certificate2Collection certificatesCollection = new X509Certificate2Collection(clientCertificate);
                //Erzeugung einer neuen TCP-Clientverbindung
                TcpClient tcpClient = new TcpClient(hostname, port);
                //Erzeugung eines gesicherten Datenstroms für den TCP-Client
                SslStream sslStream = new SslStream(tcpClient.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
                try
                {
                    //Absicherung und Authentifzierung des Datenstromes mit TLS
                    sslStream.AuthenticateAsClient(hostname, certificatesCollection, SslProtocols.Tls, false);
                    //Erzeugung eines Speicherdatenstroms
                    MemoryStream memoryStream = new MemoryStream();
                    //Erzeugung eines Schreibers, der binäre Daten in den Speicherdatenstrom schreiben kann
                    BinaryWriter writer = new BinaryWriter(memoryStream);
                    //Schreibt eine 0 als Byte an Position 0
                    writer.Write((byte)0);
                    //Schreibt eine 0 als Byte an Position 1
                    writer.Write((byte)0);
                    //Schreibt eine 32 in Bytes an Position 2
                    writer.Write((byte)32);
                    //Schreibt den Gerätetoken in Bytes an Position 3
                    writer.Write(HexStringToByteArray(deviceToken.ToUpper()));
                    //Erzeugung der Nutzlast
                    string payload = "{\"aps\":{\"alert\":\"" + notification + "\",\"badge\":1,\"sound\":\"default\"}}";
                    //Schreibt eine 0 als Byte an Position 4
                    writer.Write((byte)0);
                    //Schreibt die Nutzlastlänge in Bytes an Position 5
                    writer.Write((byte)payload.Length);
                    //Umwandlung der Nutzlast in ein Byte-Array
                    byte[] payloadBytes = System.Text.Encoding.UTF8.GetBytes(payload);
                    //Schreibt das Byte-Array an die Position 6
                    writer.Write(payloadBytes);
                    //Ausleeren des Inhaltes des Schreibers
                    writer.Flush();
                    //Schreiben des Speicherdatenstroms in ein Byte-Array
                    byte[] memoryStreamAsBytes = memoryStream.ToArray();
                    //Schreiben der Bytes in den gesicherten Datenstrom
                    sslStream.Write(memoryStreamAsBytes);
                    //Ausleeren des gesicherten Datenstroms
                    sslStream.Flush();
                    //Schließen der Verbindung
                    tcpClient.Close();
                }
                
                catch (Exception ex)
                {
                    eventLog.WriteEntry(ex.Message, EventLogEntryType.Error);
                    tcpClient.Close();
                }
            }
    
            private byte[] HexStringToByteArray(string hexString)
            {
                return Enumerable.Range(0, hexString.Length)
                         .Where(x => x % 2 == 0)
                         .Select(x => Convert.ToByte(hexString.Substring(x, 2), 16))
                         .ToArray();
            }
    
            private bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
            {
                if (sslPolicyErrors == SslPolicyErrors.None) return true;
                return false;
            }
        }
    }

    • Als Antwort markiert Marcus Runge Donnerstag, 20. April 2017 13:59
    Donnerstag, 20. April 2017 13:59

Alle Antworten

  • Hallo Marcus Runge,

    Ich habe bemerkt, dass Du diese Frage im englischen Forum gestellt hast und ich verlinke den dortigen Thread, der einen Hinweis diesbezüglich enthält:
    Apple APNS WebRequest

    Gruß,

    Ivan Dragov


    Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „IT-Pros helfen IT-Pros“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.

    Dienstag, 18. April 2017 06:26
    Moderator
  • using System;
    using System.Diagnostics;
    using System.IO;
    using System.Linq;
    using System.Net.Security;
    using System.Net.Sockets;
    using System.Security.Authentication;
    using System.Security.Cryptography.X509Certificates;
    
    namespace Pusher
    {
        public class ApplePusher
        {
            private EventLog eventLog;
    
            public ApplePusher(EventLog eventLog)
            {
                this.eventLog = eventLog;
            }
    
            public void SendNotification(string deviceToken, string notification)
            {
                //Port des Apple Pushbenachrichtigungsdienstes (APNS)
                int port = 2195;
                //Hostname für Entwicklungsbetrieb
                string hostname = "gateway.sandbox.push.apple.com";
                //Hostname für Produktionsbetrieb
                //string hostname = "gateway.push.apple.com";
                //Pfad zur Zertifikatsdatei
                string certificatePath = @"apns-certificate.p12";
                //Erzeugung eines neuen Clientzertifikates aus der Zertifikatsdatei
                X509Certificate2 clientCertificate = new X509Certificate2(File.ReadAllBytes(certificatePath), "");
                //Hinzufügen des Zertifikates zu einer Zertifikatssammlung
                X509Certificate2Collection certificatesCollection = new X509Certificate2Collection(clientCertificate);
                //Erzeugung einer neuen TCP-Clientverbindung
                TcpClient tcpClient = new TcpClient(hostname, port);
                //Erzeugung eines gesicherten Datenstroms für den TCP-Client
                SslStream sslStream = new SslStream(tcpClient.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
                try
                {
                    //Absicherung und Authentifzierung des Datenstromes mit TLS
                    sslStream.AuthenticateAsClient(hostname, certificatesCollection, SslProtocols.Tls, false);
                    //Erzeugung eines Speicherdatenstroms
                    MemoryStream memoryStream = new MemoryStream();
                    //Erzeugung eines Schreibers, der binäre Daten in den Speicherdatenstrom schreiben kann
                    BinaryWriter writer = new BinaryWriter(memoryStream);
                    //Schreibt eine 0 als Byte an Position 0
                    writer.Write((byte)0);
                    //Schreibt eine 0 als Byte an Position 1
                    writer.Write((byte)0);
                    //Schreibt eine 32 in Bytes an Position 2
                    writer.Write((byte)32);
                    //Schreibt den Gerätetoken in Bytes an Position 3
                    writer.Write(HexStringToByteArray(deviceToken.ToUpper()));
                    //Erzeugung der Nutzlast
                    string payload = "{\"aps\":{\"alert\":\"" + notification + "\",\"badge\":1,\"sound\":\"default\"}}";
                    //Schreibt eine 0 als Byte an Position 4
                    writer.Write((byte)0);
                    //Schreibt die Nutzlastlänge in Bytes an Position 5
                    writer.Write((byte)payload.Length);
                    //Umwandlung der Nutzlast in ein Byte-Array
                    byte[] payloadBytes = System.Text.Encoding.UTF8.GetBytes(payload);
                    //Schreibt das Byte-Array an die Position 6
                    writer.Write(payloadBytes);
                    //Ausleeren des Inhaltes des Schreibers
                    writer.Flush();
                    //Schreiben des Speicherdatenstroms in ein Byte-Array
                    byte[] memoryStreamAsBytes = memoryStream.ToArray();
                    //Schreiben der Bytes in den gesicherten Datenstrom
                    sslStream.Write(memoryStreamAsBytes);
                    //Ausleeren des gesicherten Datenstroms
                    sslStream.Flush();
                    //Schließen der Verbindung
                    tcpClient.Close();
                }
                
                catch (Exception ex)
                {
                    eventLog.WriteEntry(ex.Message, EventLogEntryType.Error);
                    tcpClient.Close();
                }
            }
    
            private byte[] HexStringToByteArray(string hexString)
            {
                return Enumerable.Range(0, hexString.Length)
                         .Where(x => x % 2 == 0)
                         .Select(x => Convert.ToByte(hexString.Substring(x, 2), 16))
                         .ToArray();
            }
    
            private bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
            {
                if (sslPolicyErrors == SslPolicyErrors.None) return true;
                return false;
            }
        }
    }

    • Als Antwort markiert Marcus Runge Donnerstag, 20. April 2017 13:59
    Donnerstag, 20. April 2017 13:59