iOS MDM - отправка push-уведомлений MDM из Java?

Я работаю над простым сервером управления мобильными устройствами iOS (MDM) на Java в качестве ментального упражнения и подтверждения концепции. До сих пор у меня есть ряд конечных точек службы JAX-RS RESTful, которые позволяют мне:

  • Начальная регистрация устройства
  • Начальная регистрация сертификата MDM (SCEP)
  • Регистрация сертификата устройства (SCEP)
  • Установка полезной нагрузки профиля МДМ

Мой профиль MDM выглядит примерно так. Он настраивает сертификат устройства с помощью SCEP и устанавливает информацию об URL-адресе регистрации и самом MDM:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Inc//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>PayloadVersion</key>
        <integer>1</integer>
        <key>PayloadType</key>
        <string>Configuration</string>
        <key>PayloadUUID</key>
            <string>6470eee3-88e1-44fd-b301-7e51872822dd</string>
            <key>PayloadIdentifier</key>
            <string>org.example.mymdm.checkin</string>
        <key>PayloadContent</key>
        <array>
            <dict>
                <key>PayloadContent</key>
                <dict>
                    <key>URL</key>
                    <string>https://mymdmserver:8443/mdm/scep</string>
                    <key>Name</key>
                    <string>EnrollmentCAInstance</string>
                    <key>Subject</key>
                    <array>
                        <array>
                            <array>
                                <string>O</string>
                                <string>Example, Inc.</string>
                            </array>
                        </array>
                        <array>
                            <array>
                                <string>CN</string>
                                <string>User Device Cert2</string>
                            </array>
                        </array>
                    </array>
                    <key>Challenge</key>
                    <string>MyChallengeGoesHere</string>
                    <key>Keysize</key>
                    <integer>2048</integer>
                    <key>Key Type</key>
                    <string>RSA</string>
                    <key>Key Usage</key>
                    <integer>5</integer>
                </dict>
                <key>PayloadDescription</key>
                <string>Provides device encryption identity</string>
                <key>PayloadUUID</key>
                <string>be730dbc-3d6e-462c-8368-34cec86e2acd</string>
                <key>PayloadType</key>
                <string>com.apple.security.scep</string>
                <key>PayloadDisplayName</key>
                <string>Encryption Identity</string>
                <key>PayloadVersion</key>
                <integer>1</integer>
                <key>PayloadOrganization</key>
                <string>Example, Inc.</string>
                <key>PayloadIdentifier</key>
                <string>com.example.profileservice.scep.be730dbc-3d6e-462c-8368-34cec86e2acd</string>
            </dict>
            <dict>
                <key>AccessRights</key>
                <integer>8191</integer>
                <key>CheckInURL</key>
                <string>https://mymdmserver:8443/mdm/checkin</string>
                <key>CheckOutWhenRemoved</key>
                <true/>
                <key>IdentityCertificateUUID</key>
                <string>be730dbc-3d6e-462c-8368-34cec86e2acd</string>
                <key>PayloadDescription</key>
                <string>Checkin</string>
                <key>PayloadDisplayName</key>
                <string>Checkin</string>
                <key>PayloadIdentifier</key>
                <string>com.apple.mdm.995191e6-b387-47c6-98d1-c00a25d95047</string>
                <key>PayloadOrganization</key>
                <string>Gener-Tech</string>
                <key>PayloadType</key>
                <string>com.apple.mdm</string>
                <key>PayloadUUID</key>
                <string>527228e9-8094-40b8-89ce-7c5b09ad348b</string>
                <key>PayloadVersion</key>
                <integer>1</integer>
                <key>ServerURL</key>
                <string>https://mymdmserver:8443/mdm/checkin</string>
                <key>SignMessage</key>
                <true/>
                <key>Topic</key>
                <string>com.apple.mgmt.External.*</string>
                <key>UseDevelopmentAPNS</key>
                <false/>
            </dict>
        </array>
    </dict>
</plist>

После завершения беспроводной установки я вижу конфигурацию и сертификат устройства на моем устройстве iOS. Я также вижу вызов моей конечной точки /checkin, содержащей значения PushMagic и токена устройства для APNS. Именно в этот момент я сталкиваюсь с контрольно-пропускным пунктом.

Я использую библиотеку java-apns, чтобы попытаться отправить push-уведомление через APNS на мое устройство с помощью PushMagic и токена устройства. Мой звонок выглядит примерно так:

ApnsService apns = APNS.newService().withCert(Thread.currentThread().getContextClassLoader().getResourceAsStream("MDM_APNS_Cert.p12"),
                            certPassword)
                    .withAppleDestination(true).build();

byte[] tokenBytes = Base64.decodeBase64(deviceToken.getBytes());
        String hexToken = Hex.encodeHexString(tokenBytes);
        String pushNotificationPayload = APNS.newPayload().mdm(pushMagic).build();
        ApnsNotification response = apns.push(hexToken, pushNotificationPayload);

Однако, когда я пытаюсь отправить push-уведомление, я вижу ошибки в моих журналах, которые выглядят примерно так:

13:29:55,133 DEBUG [com.notnoop.apns.internal.ApnsConnectionImpl] (MonitoringThread-2) Error-response packet 080800000002
13:29:55,133 DEBUG [com.notnoop.apns.internal.Utilities] (MonitoringThread-2) close 6a86b59d[SSL_RSA_WITH_3DES_EDE_CBC_SHA: Socket[addr=gateway.push.apple.com/17.188.147.157,port=2195,localport=58884]]
13:29:55,133 DEBUG [com.notnoop.apns.internal.ApnsConnectionImpl] (MonitoringThread-2) Closed connection cause=INVALID_TOKEN; id=2
13:29:55,133 DEBUG [com.notnoop.apns.internal.ApnsConnectionImpl] (MonitoringThread-2) Candidate for removal, message id 2
13:29:55,133 DEBUG [com.notnoop.apns.internal.ApnsConnectionImpl] (MonitoringThread-2) Bad message found 2
13:29:55,133 DEBUG [com.notnoop.apns.internal.ApnsConnectionImpl] (MonitoringThread-2) delegate.messageSendFailed, message id 2
13:29:55,133 DEBUG [com.notnoop.apns.internal.ApnsConnectionImpl] (MonitoringThread-2) resending 0 notifications
13:29:55,133 DEBUG [com.notnoop.apns.internal.ApnsConnectionImpl] (MonitoringThread-2) Monitoring input stream closed by EOF
13:29:55,133 DEBUG [com.notnoop.apns.internal.Utilities] (MonitoringThread-2) close 6a86b59d[SSL_RSA_WITH_3DES_EDE_CBC_SHA: Socket[addr=gateway.push.apple.com/17.188.147.157,port=2195,localport=58884]]
13:29:55,133 DEBUG [com.notnoop.apns.internal.ApnsConnectionImpl] (MonitoringThread-2) draining buffer

Есть идеи, что здесь может происходить? Насколько я понимаю, push-уведомление должно быть получено устройством iOS, а затем оно будет называть URL-адрес, определенный в профиле MDM, как ServerURL. Это не правильно? Я неправильно понимаю поток здесь? Как я могу исправить проблему с помощью моего push-уведомления MDM?

ОБНОВЛЕНИЕ: Итак, я попробовал протестировать 2 способа: использование библиотеки java-apns и использование curl. С curl моя команда выглядит так:

curl -vk -E ./MDMPushCert.pem -d '{"aps":{"mdm":"<PUSH MAGIC VALUE FROM CHECKIN>"}}' -H "apns-topic: com.apple.mgmt.XServer.<UUID FROM PUSH CERT>" -H "apns-priority: 10"  https://api.push.apple.com/3/device/<DEVICE TOKEN FROM CHECKIN>

Команда curl завершается неудачно, однако с ошибкой {"reason":"BadDeviceToken"}несмотря на то, что я копирую и вставляю значение, предоставленное устройством при вызове /checkin конечная точка. Полный вывод выглядит так:

*   Trying 17.188.152.35...
* TCP_NODELAY set
* Connected to api.push.apple.com (17.188.152.35) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/cert.pem
  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Request CERT (13):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Certificate (11):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS handshake, CERT verify (15):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=api.push.apple.com; OU=management:idms.group.533599; O=Apple Inc.; ST=California; C=US
*  start date: Sep  5 17:11:04 2017 GMT
*  expire date: Oct  5 17:11:04 2019 GMT
*  issuer: CN=Apple IST CA 2 - G1; OU=Certification Authority; O=Apple Inc.; C=US
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x7fdbf7809400)
> POST /3/device/<TOKEN FROM CHECKIN>
0 HTTP/2
> Host: api.push.apple.com
> User-Agent: curl/7.54.0
> Accept: */*
> apns-topic: com.apple.mgmt.XServer.<UUID FROM APNS CERT>
> apns-priority: 10
> Content-Length: 54
> Content-Type: application/x-www-form-urlencoded
> 
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
* We are completely uploaded and fine
< HTTP/2 400 
< apns-id: 7E178A20-9C17-8E21-592F-185E02D17F14
< 
* Connection #0 to host api.push.apple.com left intact
{"reason":"BadDeviceToken"}

Сам push-сертификат был сгенерирован путем установки macOS Server на macOS High Sierra и последующего экспорта сертификата, сгенерированного при установке Profile Server. Чего я не понимаю, так это того, почему я получаю неверную ошибку токена, когда токен пришел непосредственно с самого устройства. Я предполагаю, что это та же самая ошибка, вызывающая сбой моего вызова java-apns. Результат этого вызова выглядит следующим образом:

09:04:10,735 DEBUG [com.notnoop.apns.internal.ApnsConnectionImpl] (default task-75) sendMessage Message(Id=1; Token=7BC93DC7AF930EED7379899B4E3FB9676DDABDCBA7B4F39D5E7654ECDC3F1DD0; Payload={"mdm":"4A846CEF-3241-426E-B451-F258E4B1ABA6"}) fromBuffer: false
09:04:10,803 DEBUG [com.notnoop.apns.internal.ApnsConnectionImpl] (default task-75) Connected new socket 3e1dae5f[SSL_NULL_WITH_NULL_NULL: Socket[addr=gateway.push.apple.com/17.188.168.12,port=2195,localport=64265]]
09:04:10,803 DEBUG [com.notnoop.apns.internal.ApnsConnectionImpl] (default task-75) Launching Monitoring Thread for socket 3e1dae5f[SSL_NULL_WITH_NULL_NULL: Socket[addr=gateway.push.apple.com/17.188.168.12,port=2195,localport=64265]]
09:04:10,805 DEBUG [com.notnoop.apns.internal.ApnsConnectionImpl] (default task-75) Made a new connection to APNS
09:04:10,805 DEBUG [com.notnoop.apns.internal.ApnsConnectionImpl] (MonitoringThread-1) Started monitoring thread
09:04:10,920 DEBUG [com.notnoop.apns.internal.ApnsConnectionImpl] (default task-75) draining buffer
09:04:10,921 DEBUG [com.mymdm.rest.test.TestMDMService] (default task-75) push(HttpServletRequest, HttpServletResponse) - ApnsNotification response=Message(Id=1; Token=7BC93DC7AF930EED7379899B4E3FB9676DDABDCBA7B4F39D5E7654ECDC3F1DD0; Payload={"mdm":"4A846CEF-3241-426E-B451-F258E4B1ABA6"})
09:04:10,921 DEBUG [com.mymdm.rest.test.TestMDMService] (default task-75) push(HttpServletRequest, HttpServletResponse) - end
09:04:10,962 DEBUG [com.notnoop.apns.internal.ApnsConnectionImpl] (MonitoringThread-1) Error-response packet 080800000001
09:04:10,962 DEBUG [com.notnoop.apns.internal.Utilities] (MonitoringThread-1) close 3e1dae5f[SSL_RSA_WITH_3DES_EDE_CBC_SHA: Socket[addr=gateway.push.apple.com/17.188.168.12,port=2195,localport=64265]]
09:04:10,964 DEBUG [com.notnoop.apns.internal.ApnsConnectionImpl] (MonitoringThread-1) Closed connection cause=INVALID_TOKEN; id=1
09:04:10,964 DEBUG [com.notnoop.apns.internal.ApnsConnectionImpl] (MonitoringThread-1) Candidate for removal, message id 1
09:04:10,964 DEBUG [com.notnoop.apns.internal.ApnsConnectionImpl] (MonitoringThread-1) Bad message found 1
09:04:10,964 DEBUG [com.notnoop.apns.internal.ApnsConnectionImpl] (MonitoringThread-1) delegate.messageSendFailed, message id 1
09:04:10,964 DEBUG [com.notnoop.apns.internal.ApnsConnectionImpl] (MonitoringThread-1) resending 0 notifications
09:04:10,964 DEBUG [com.notnoop.apns.internal.ApnsConnectionImpl] (MonitoringThread-1) Monitoring input stream closed by EOF
09:04:10,965 DEBUG [com.notnoop.apns.internal.Utilities] (MonitoringThread-1) close 3e1dae5f[SSL_RSA_WITH_3DES_EDE_CBC_SHA: Socket[addr=gateway.push.apple.com/17.188.168.12,port=2195,localport=64265]]
09:04:10,965 DEBUG [com.notnoop.apns.internal.ApnsConnectionImpl] (MonitoringThread-1) draining buffer

0 ответов

Другие вопросы по тегам