-
Notifications
You must be signed in to change notification settings - Fork 113
not working in Chrome #33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Can you share the Java code that you use to send the notification? |
Here is the simplified version of the class (that is part of a much bigger system) used for sending browser push notification. import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.spec.InvalidKeySpecException;
import javax.annotation.PostConstruct;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpResponse;
import org.bouncycastle.jce.ECNamedCurveTable;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.jce.spec.ECPublicKeySpec;
import org.bouncycastle.math.ec.ECPoint;
import org.springframework.beans.factory.annotation.Autowired;
import nl.martijndwars.webpush.Notification;
import nl.martijndwars.webpush.PushService;
import nl.martijndwars.webpush.Subscription;
import nl.martijndwars.webpush.Utils;
public class BrowserClient
{
public void send(final String browserEndPoint, final String browserPublicKey, final String browserPrivateKey, final String browserPayload)
{
final Subscription subscription = new Subscription();
subscription.keys = subscription.new Keys();
subscription.endpoint = browserEndPoint;
subscription.keys.p256dh = browserPublicKey;
subscription.keys.auth = browserPrivateKey;
final String payload = browserPayload;
sendPushMessage(subscription, payload);
}
private void sendPushMessage(final Subscription subscription, final String payload)
{
try
{
final Notification notification = new Notification(subscription.endpoint,
getUserPublicKey(Base64.decodeBase64(subscription.keys.p256dh)),
Base64.decodeBase64(subscription.keys.auth),
payload.getBytes());
final PushService pushService = new PushService();
pushService.setPublicKey(publicKey);
pushService.setPrivateKey(privateKey);
final HttpResponse response = pushService.send(notification);
if(response.getStatusLine().getStatusCode() != 201)
{
throw new RuntimeException(response.toString());
}
}
catch(final RuntimeException e)
{
throw e;
}
catch(final Exception e)
{
throw new RuntimeException(payload, e);
}
}
private PublicKey getUserPublicKey(final byte[] key) throws InvalidKeySpecException
{
final ECPoint point = ecSpec.getCurve().decodePoint(key);
final ECPublicKeySpec pubSpec = new ECPublicKeySpec(point, ecSpec);
return keyFactory.generatePublic(pubSpec);
}
@PostConstruct
private void init()
{
try
{
if(Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null)
{
Security.addProvider(new BouncyCastleProvider());
}
keyFactory = KeyFactory.getInstance("ECDH", BouncyCastleProvider.PROVIDER_NAME);
ecSpec = ECNamedCurveTable.getParameterSpec("secp256r1");
if(ecSpec == null)
{
throw new RuntimeException("ecSpec == null");
}
publicKey = Utils.loadPublicKey(browserPublicKey);
privateKey = Utils.loadPrivateKey(browserPrivateKey);
}
catch(final Exception e)
{
throw new RuntimeException("init", e);
}
}
@Autowired
private String browserPublicKey;
@Autowired
private String browserPrivateKey;
private PublicKey publicKey;
private PrivateKey privateKey;
private ECParameterSpec ecSpec;
private KeyFactory keyFactory;
} |
I tried to reproduce your problem with the latest version of this library, but was unable to do so. I took the following steps:
{"endpoint":"https://fcm.googleapis.com/fcm/send/epl45v0X9BE:APA91bG8kPTgi8ZP67QlXBU8Qwfp_ONhM1xDBs9quNcb-lZYF5OSsdDYSvS6qHXaEjag9uhi_np7KIbOZ-vheIOKunPHl3huEeb8Emc_gcmN5RBYiSfVx3Bgv6DRNZHnLqqwL-wdfR8H","keys":{"p256dh":"BP8-PfGgU6Vt3ZcSZEaY_PLUTWMOc4JLtpcwDdX1qEY-AVk4g4qg8Mk2a_69a1-1Dz87gVAmmOCOjG-2BCZotfQ=","auth":"OoWUPKs8kQK7sE69l-po6A=="}}
Security.addProvider(new BouncyCastleProvider());
String publicKey = "BLzPK96e2_tX5pE9HA9D6j_H1fkZi3yEgpG1HGifioFtM1wWSoJBcV7vWAsXzIVngaVAm5lmnD2TwvF46ouYx0M";
String privateKey = "GtGG-dCPNMi5nTw2jwsvHnTIGIeQudJW26uIoYgglDs";
Subscription subscription = new Gson().fromJson("{\"endpoint\":\"https://fcm.googleapis.com/fcm/send/dCClbSTzmVs:APA91bHKRjr11h7NzhpmwkVLHoa2EX6a30CrbRGS5yGeE_-uRCJA7FWwn52gnzbDB9gnI_MeBAJcLQ0Ad_T-Z0JK2Tbno3b28BU8F3nQQnefzB2lrBt21Yn6irUCyQw7p6hzq9MVOiTB\",\"keys\":{\"p256dh\":\"BEyx_O7C0K8tXrn2z6XWWPvxjLK_D-usNDSzTwlDe3XMa5oPTTSNxnzFTLsulM5orOZigO6oZxCtib8gCPTfVv8=\",\"auth\":\"MUPHKjaPCkVgtbBV8Ywb7g==\"}}", Subscription.class);
Notification notification = new Notification(subscription, "Hello, world");
PushService pushService = new PushService();
pushService.setPublicKey(publicKey);
pushService.setPrivateKey(privateKey);
pushService.setSubject("mailto:[email protected]");
HttpResponse httpResponse = pushService.send(notification);
System.out.println(httpResponse.getStatusLine().getStatusCode());
System.out.println(IOUtils.toString(httpResponse.getEntity().getContent(), StandardCharsets.UTF_8)); When running this code, the message arrives in Chrome 59.0. Let me know if this is working for you. |
I did the exact procedure you described here but I'm getting: Mind you, in v3.0.0 PushService.setPrivateKey and setPublicKey only accept PrivateKey and PublicKey objects so I had to pass them in the PushService contructor. Everything in the code is the same as in yours. The exception occurs while executing:
|
I am also having the same issue. I have tested using the exact same encryption keys and subscription objects against the nodejs module vs this java library. I get the 400s in Chrome when using the java library. NodeJS w/ GC Subscription:
Java w/ GC Subscription:
|
Thanks for the report @patrickathompson. I did not find the time to look into this yet, but I will do so as soon as possible. |
Same for me, I can't meka it work yet, I'm getting HTTP/1.1 400 UnauthorizedRegistration on each request |
more information by testing chrome: |
To be fair, it has worked for me in the past. At first, I thought it was something I was doing wrong, or the code my application was using. After following the steps @martijndwars mentions in his Jun 22nd post several times, I am getting intermittent results. Sometimes it works and sometimes it doesn't. It's also worth noting, that when it does work, it will always work, and when it doesn't work, it will never work. I have not been able to identify any patterns other than that. I have provided an example scenario where the 400 issue occurs that does not use any of my own code. Hopefully that should be enough evidence to investigate the issue. I have also done some code analysis and compared the java source against the nodejs source, and I am noticing some deviations in the algorithms used. I don't quite understand everything about how the authentication works, or I would have attempted a patch, but I can clearly see the java library is authenticating in a different manner than the nodejs module. |
This could be a problem with the keys (or the way we encode/decode them in Java code). I remember the NodeJS version had a problem when the base64 encoding needed padding. Thanks for the extra info, I'll look into this. |
We have experienced almost the exact same situation as @patrickathompson. Three sets of keys, all work with the NodeJS lib, one set works consistently with the Java lib, the other two fail consistently with the Java lib. I believe that the problem with our keys is arising from the use of ECDH as the algorithm to load the VAPID public key and private key. We have tested switching this to EC and found that all three sets of keys were able to send web pushes successfully. |
Interesting. How did you generate these three keys? |
Two sets (one working, one not) were generated using the NodeJS web push library: |
When i make the VAPID keys with the node library, the c# library or on https://web-push-codelab.glitch.me/ my application works with he node library, the c# library but not with the java library (i get the problems mentioned above) When i make the VAPID keys with openssl my application works with he node library, the c# library and also with the java library |
Ah, I figured out what is going wrong. What happens is that (1) the base64-encoded private key is converted to an array of bytes and (2) this array of bytes is converted to a BigInteger. However, during (2) the array of bytes is assumed to represent two's complement binary, but it actually represents unsigned binary. I've released version 3.0.2 that fixes this issue. You can now use the keys from web-push-codelab.glitch.me without any problems. I'm closing the issue, but feel free to leave a comment if there's still a problem. |
Following the article about sending web push notifications I managed to make it work in both Chrome and Firefox browsers. Using the webpush-java I managed to make it send notifications to Firefox, but not to Chrome. When sending to Chrome, I am getting return code 400 UnauthorizedRegistration.
The web server I use is web server for Chrome, as suggested in the article. I use the corresponding applicationServerPublicKey, as generated in the companion site, and use corresponding public/private keys (different for Firefox and Chrome).
Searching the internet didn't yield any actionable steps. Any suggestions as to what to try/how to get to the bottom of this? Please let me know if any more/additional information is needed.
Thanks!
The text was updated successfully, but these errors were encountered: