Search code examples
javapush-notificationsafariweb-pushsafari-push-notifications

Sending Push Notifications to Safari from Java


I am trying to get the Web Push API to work with my app and Safari on iOS. I can register fine in Safari ... But, when trying to send my request to the endpoint I receive a 403 with reason: BadJwtToken. I've verified the token being sent in the Authentication header is valid. Also, the code I am using to send the Push request works perfectly on Chrome & Edge. Has anyone else experienced this behaviour? Excerpt from the log below showing outgoing request and response. Any suggestions would be greatly appreciated.

2023-02-23 16:32:05.882 DEBUG 17412 --- [/O dispatcher 1] org.apache.http.wire                     : http-outgoing-0 >> "POST /QKmekz9T3h2DpblQXdmVpVJPWtR145PdK-WYRMt4zldrXBOGsnqLluGtB9PFehMfoTXASt2-8pTmnRzUB0P0XMMDgX-tWdgIvL1YptpQdI_pVB3EEsnbR0LUStq97BUMIrMG_yVI6eUYJVigQtVgq0Fcl0D8k7tt9U8WEBbLmFc HTTP/1.1[\r][\n]"
2023-02-23 16:32:05.882 DEBUG 17412 --- [/O dispatcher 1] org.apache.http.wire                     : http-outgoing-0 >> "Authorization: WebPush eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9.eyJhdWQiOiJodHRwczovL3dlYi5wdXNoLmFwcGxlLmNvbSIsImV4cCI6MTY3NzIxMzEyNSwic3ViIjoibWFpbHRvOiA8aW5mb0BtZHNnbG9iYWwuY29tPiJ9.7P42kj123WHHWk0AaRiFiIb1nTx1GaeaY3xmDWJbD3tlNQn_Rxw-jZPZOzxb1YeN7y2qWO9qoSIAg22_SwZuOQ[\r][\n]"
2023-02-23 16:32:05.882 DEBUG 17412 --- [/O dispatcher 1] org.apache.http.wire                     : http-outgoing-0 >> "Content-Encoding: aesgcm[\r][\n]"
2023-02-23 16:32:05.882 DEBUG 17412 --- [/O dispatcher 1] org.apache.http.wire                     : http-outgoing-0 >> "Encryption: salt=ski4AOi0Xc5HCo2zvuzDfg[\r][\n]"
2023-02-23 16:32:05.882 DEBUG 17412 --- [/O dispatcher 1] org.apache.http.wire                     : http-outgoing-0 >> "TTL: 2419200[\r][\n]"
2023-02-23 16:32:05.882 DEBUG 17412 --- [/O dispatcher 1] org.apache.http.wire                     : http-outgoing-0 >> "Crypto-Key: dh=BGLGnvvc-_jNZuHicms4eBijG7flOSUXHAte5GF2GtEQ1viZoL_NlzakYJBGMJrHHEbuxr76mPh8mAF0fZ2KFCo=;p256ecdsa=BKjlmDj7I5JkC3I2clsddfl7rklur8OIIx8_EKvDfpdrebwKRebZChSCIqKp64nkkyq4IWpUlVoDQ2CKK4axUjo[\r][\n]"
2023-02-23 16:32:05.882 DEBUG 17412 --- [/O dispatcher 1] org.apache.http.wire                     : http-outgoing-0 >> "Content-Type: application/octet-stream[\r][\n]"
2023-02-23 16:32:05.882 DEBUG 17412 --- [/O dispatcher 1] org.apache.http.wire                     : http-outgoing-0 >> "Content-Length: 202[\r][\n]"
2023-02-23 16:32:05.882 DEBUG 17412 --- [/O dispatcher 1] org.apache.http.wire                     : http-outgoing-0 >> "Host: web.push.apple.com[\r][\n]"
2023-02-23 16:32:05.882 DEBUG 17412 --- [/O dispatcher 1] org.apache.http.wire                     : http-outgoing-0 >> "Connection: Keep-Alive[\r][\n]"
2023-02-23 16:32:05.882 DEBUG 17412 --- [/O dispatcher 1] org.apache.http.wire                     : http-outgoing-0 >> "User-Agent: Apache-HttpAsyncClient/4.1.4 (Java/1.8.0_362)[\r][\n]"
2023-02-23 16:32:05.882 DEBUG 17412 --- [/O dispatcher 1] org.apache.http.wire                     : http-outgoing-0 >> "[\r][\n]"
2023-02-23 16:32:05.882 DEBUG 17412 --- [/O dispatcher 1] org.apache.http.wire                     : http-outgoing-0 >> "[0xffffffc6][0x8]1_[0xfffffff1][0xffffffaa][0x8]1m[0xfffffff3][0xffffffd9]0:[0xffffffd8][0x1d]2Y[0xffffff9c][0xffffffae][0x8][0xfffffffe]gVs[0xffffffec][0xffffffcd]~[0x15][0xffffff8e][0xc][0xfffffff7][0xffffff83][0x12]B[0xffffffcc]y[0xffffffd8][0xffffff8d]}C{mCL[0xffffffee]0Z[0xffffffc3][0xffffff9a])20[0xffffffc8]G[0xffffffdb]<t[0x6]a[0xffffff84]q[0x0][0xffffffc8][0xffffffa0][0xffffffe3][0xffffff95][0xffffff82][0xffffffdf]3'[0xffffffeb][0xffffffbf][0xffffffa7]H$\1[0xffffffaf]E[0xffffffb4]0[0xffffffbe][0xb]3[0xffffffdf]W[0x5],[0xffffffed][0xffffffeb]dR[0xffffffd6][0xffffffc5]Mk[0xffffffc7][0xffffffbe][0x18]%[0xffffffd5]A[0xffffffec]~f[0xffffffd5][0xfffffff3](u[0xffffffc4]J{kKG[0xffffff8f]7NaZ<1:F@[0xf][0xffffff97][0xffffffca].K[0xffffffea][0xffffffb1][0xfffffffd][0xfffffff6][0xffffff9d][0xffffffc9][0x7][0xffffff86]r[0xffffff95]S[0xfffffff4][0xffffffba]3[0xffffffe7][0xfffffff8][0xffffffd0];[0xffffffce][0xffffffd1][0xffffffce][0xffffffe7][0xffffffd1][0xffffffa2][0xffffffa0][0xffffffba]Z[0xffffff80][0xffffffa6][0x2]X[0xffffff9c][0xffffff91][0xffffffda][0xffffff98][0x12][0xffffffda]z[0xffffffe0]q7[0xffffffa9]F[0x0][0xffffffe7]3R[0xffffff9d]M\v:xU[0xffffffa4][0xffffffa6][0xffffffdf];na[0x1c][0xffffffe1]>[0xffffff82](2[0xffffffcf]-![0xffffff83][0xffffffd7][0xffffffc9]"
2023-02-23 16:32:05.883 DEBUG 17412 --- [/O dispatcher 1] o.a.h.i.nio.client.InternalIODispatch    : http-outgoing-0 [ACTIVE] Request ready
2023-02-23 16:32:05.883 DEBUG 17412 --- [/O dispatcher 1] h.i.n.c.ManagedNHttpClientConnectionImpl : http-outgoing-0 10.154.0.20:56270<->17.188.172.94:443[ACTIVE][r:w][ACTIVE][r][NOT_HANDSHAKING][0][0][0]: Event cleared [w]
2023-02-23 16:32:05.975 DEBUG 17412 --- [/O dispatcher 1] h.i.n.c.ManagedNHttpClientConnectionImpl : http-outgoing-0 10.154.0.20:56270<->17.188.172.94:443[ACTIVE][r:r][ACTIVE][r][NOT_HANDSHAKING][0][0][0]: 158 bytes read
2023-02-23 16:32:05.975 DEBUG 17412 --- [/O dispatcher 1] org.apache.http.wire                     : http-outgoing-0 << "HTTP/1.1 403 Forbidden[\r][\n]"
2023-02-23 16:32:05.975 DEBUG 17412 --- [/O dispatcher 1] org.apache.http.wire                     : http-outgoing-0 << "content-type: text/plain; charset=UTF-8[\r][\n]"
2023-02-23 16:32:05.975 DEBUG 17412 --- [/O dispatcher 1] org.apache.http.wire                     : http-outgoing-0 << "content-length: 24[\r][\n]"
2023-02-23 16:32:05.975 DEBUG 17412 --- [/O dispatcher 1] org.apache.http.wire                     : http-outgoing-0 << "apns-id: 3253F680-762D-BC6F-9218-CB0F250A9142[\r][\n]"
2023-02-23 16:32:05.975 DEBUG 17412 --- [/O dispatcher 1] org.apache.http.wire                     : http-outgoing-0 << "[\r][\n]"
2023-02-23 16:32:05.975 DEBUG 17412 --- [/O dispatcher 1] org.apache.http.wire                     : http-outgoing-0 << "{"reason":"BadJwtToken"}"
2023-02-23 16:32:05.978 DEBUG 17412 --- [/O dispatcher 1] org.apache.http.headers                  : http-outgoing-0 << HTTP/1.1 403 Forbidden
2023-02-23 16:32:05.978 DEBUG 17412 --- [/O dispatcher 1] org.apache.http.headers                  : http-outgoing-0 << content-type: text/plain; charset=UTF-8
2023-02-23 16:32:05.978 DEBUG 17412 --- [/O dispatcher 1] org.apache.http.headers                  : http-outgoing-0 << content-length: 24
2023-02-23 16:32:05.978 DEBUG 17412 --- [/O dispatcher 1] org.apache.http.headers                  : http-outgoing-0 << apns-id: 3253F680-762D-BC6F-9218-CB0F250A9142
2023-02-23 16:32:05.978 DEBUG 17412 --- [/O dispatcher 1] o.a.h.i.nio.client.InternalIODispatch    : http-outgoing-0 [ACTIVE(24)] Response received

I've tried pretty much everything I can think of at this stage


Solution

  • For me the problem was missing or incorrectly formatted sub parameter. It is NOT mandatory according to the protocol documentation, but Apple (and actually Mozilla as well) decided that it's required. Apple states, that one of the reasons of 403 BadJwtToken is this: "The JWT subject claim isn’t a URL or mailto:." (See the documentation) When I started providing the sub parameter as mailto:%my_email_address%, everything works fine for me. You may look at the discussion here I hope it will help.