RobotsAndPencils / buford

A push notification delivery engine for the new HTTP/2 APNS service.
MIT License
475 stars 52 forks source link

[WIP] Support Provider Authentication Tokens (JWT) #88

Open nathany opened 8 years ago

nathany commented 8 years ago

continuing from #66 to solve #63.

Provider Authentication Tokens documentation is now public. https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/APNsProviderAPI.html#//apple_ref/doc/uid/TP40008194-CH101-SW21

nathany commented 8 years ago

I have a signing key, which is a .p8 file that looks like PEM format.

Same token for all apps on a Team. The signing key doesn't expire.

You should construct a token with header containing a 10 character Key ID (kid). The token claims portion contains Issuer (iss) which is a 10 character Team ID.

The token must be signed with the Elliptic Curve Digital Signature Algorithm (ECDSA) using the P-256 curve and the SHA-256 hash algorithm (ES256)

Presumably a JWT library will take care of this, but can also look at https://github.com/gtank/cryptopasta.

tokens can be reused but need to be periodically regenerated:

APNs will reject push messages with an Expired Provider Token error if the token issue timestamp is not within the last hour.

But not too often 429 TooManyProviderTokenUpdates

When you connect to APNs without a provider certificate, only one stream is allowed on the connection until you send a push message with valid token.

403 MissingProviderToken, InvalidProviderToken, ExpiredProviderToken

codecov-io commented 8 years ago

Current coverage is 53.68% (diff: 11.11%)

Merging #88 into master will decrease coverage by 2.48%

@@             master        #88   diff @@
==========================================
  Files            11         11          
  Lines           308        326    +18   
  Methods           0          0          
  Messages          0          0          
  Branches          0          0          
==========================================
+ Hits            173        175     +2   
- Misses          116        132    +16   
  Partials         19         19          

Powered by Codecov. Last update d6d71af...d4fd0bb

nathany commented 8 years ago

For concurrent use, it would be useful to have access to maxConcurrentStreams https://github.com/golang/go/issues/17265 instead of guessing how many workers to use (1, 500, something else).

Blocking when Transport hits max concurrent streams could prevent the error situations, whether in x/net/http2 or Buford. https://github.com/golang/go/issues/13774 Still would be guessing at the optimal number of workers (500?).

nathany commented 7 years ago

This is blocked on the same thing as apns2:

https://github.com/sideshow/apns2/pull/43#issuecomment-274652089

froodian commented 7 years ago

https://github.com/golang/go/issues/13774 has been closed, I wonder if this is solvable now? I don't have a lot of the context on the literals of what's required to support JWT here yet, but I do have a fair amount of demand signal for this in my use-case - could you let me know if this is something you might continue work on in the nearish future (or if something is still blocking it)? Otherwise I'll probably work to try to carve out time to get up to speed and implement this in the next few months. Thank you!

felipejfc commented 7 years ago

APNS2 maintainer has merged something similar to this: https://github.com/sideshow/apns2/pull/43#issuecomment-332144869

regards

nathany commented 7 years ago

Sorry for the lack of maintenance and responsiveness on this.

The client that was sponsoring this work decided to use Elixir for their project instead, so it hasn't received much attention. Happy to look at a fresh pull request if someone has a chance to fully implement this.

nathany commented 6 years ago

NOTE: https://go-review.googlesource.com/c/net/+/85855

nathany commented 5 years ago

Related: https://github.com/golang/go/issues/27753

https://go-review.googlesource.com/c/net/+/151857/ "http2: revert Transport's strict interpretation of MAX_CONCURRENT_STREAMS"