如何在C#中实现基于Apple令牌的推送通知(使用p8文件)? [英] How to implement apple token based push notifications (using p8 file) in C#?

查看:287
本文介绍了如何在C#中实现基于Apple令牌的推送通知(使用p8文件)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于具有某些基于聊天功能的应用程序,我想添加推送通知支持以接收新消息. 我想做的是使用来自Apple的新的基于令牌的身份验证(.p8文件),但是我找不到有关服务器部分的更多信息.

我遇到了以下帖子: 如何在C#中使用APNs身份验证密钥(.p8文件)?

但是答案并不令人满意,因为有关如何操作的细节并不多

  • 与APN建立连接
  • 使用p8文件(某种编码除外)
  • 将数据发送到Apple Push Notification Service

解决方案

您目前无法在原始.NET Framework上真正做到这一点.新的基于JWT的APNS服务器仅使用HTTP/2,而.NET Framework尚不支持.

但是,只要您满足以下先决条件,.NET Core的System.Net.Http版本就可以:

  • 在Windows上,您必须运行Windows 10周年纪念版(v1607)或更高版本,或者运行Windows Server 2016的等效版本(我认为).
  • 在Linux上,您必须具有支持HTTP/2的libcurl版本.
  • 在macOS上,您必须编译支持HTTP/2的libcurl,然后使用DYLD_INSERT_LIBRARIES环境变量才能加载您的自定义版本libcurl.

如果确实需要,您应该能够在.NET Framework中使用.NET Core的System.Net.Http版本.

我不知道在Mono,Xamarin或UWP上会发生什么.

那么您需要做三件事:

  1. 解析已获得的私钥.当前这是一个ECDSA密钥,您可以将其加载到System.Security.Cryptography.ECDsa对象中.
    • 在Windows上,您可以使用CNG API.解析密钥文件的base64编码的DER部分后,您可以使用new ECDsaCng(CngKey.Import(data, CngKeyBlobFormat.Pkcs8PrivateBlob))创建密钥.
    • 在macOS或Linux上,没有受支持的API,您必须自己解析DER结构或使用第三方库.
  2. 创建一个JSON Web令牌/承载令牌.如果您使用NuGet中的System.IdentityModel.Tokens.Jwt包,这非常简单.您将需要Apple的密钥ID和团队ID.

public static string CreateToken(ECDsa key, string keyID, string teamID)
{
    var securityKey = new ECDsaSecurityKey(key) { KeyId = keyID };
    var credentials = new SigningCredentials(securityKey, "ES256");

    var descriptor = new SecurityTokenDescriptor
    {
          IssuedAt = DateTime.Now,
          Issuer = teamID,
          SigningCredentials = credentials
    };

    var handler = new JwtSecurityTokenHandler();
    var encodedToken = handler.CreateEncodedJwt(descriptor);
    return encodedToken;
}

  1. 发送一个HTTP/2请求.这是正常现象,但是您需要做两件事:

    1. yourRequestMessage.Version设置为new Version(2, 0)以便使用HTTP/2发出请求.
    2. yourRequestMessage.Headers.Authorization设置为new AuthenticationHeaderValue("bearer", token)以便为承载身份验证令牌/JWT提供您的请求.

    然后将您的JSON放入HTTP请求中,并将其发布到正确的URL.

For an app with some kind of chat based features I want to add push notification support for receiving new messages. What I want to do is use the new token based authentication (.p8 file) from Apple, but I can't find much info about the server part.

I came across the following post: How to use APNs Auth Key (.p8 file) in C#?

However the answer was not satisfying as there was not much detail about how to:

  • establish a connection with APNs
  • use the p8 file (except for some kind of encoding)
  • send data to the Apple Push Notification Service

解决方案

You can't really do this on raw .NET Framework at the moment. The new JWT-based APNS server uses HTTP/2 only, which .NET Framework does not yet support.

.NET Core's version of System.Net.Http, however, does, provided you meet the following prerequisites:

  • On Windows, you must be running Windows 10 Anniversary Edition (v1607) or higher, or the equivalent build of Windows Server 2016 (I think).
  • On Linux, you must have a version of libcurl that supports HTTP/2.
  • On macOS, you have to compile libcurl with support for HTTP/2, then use the DYLD_INSERT_LIBRARIES environment variable in order to load your custom build of libcurl.

You should be able to use .NET Core's version of System.Net.Http in the .NET Framework if you really want.

I have no idea what happens on Mono, Xamarin or UWP.

There are then three things you have to do:

  1. Parse the private key that you have been given. This is currently an ECDSA key, and you can load this into a System.Security.Cryptography.ECDsa object.
    • On Windows, you can use the CNG APIs. After parsing the base64-encoded DER part of the key file, you can then create a key with new ECDsaCng(CngKey.Import(data, CngKeyBlobFormat.Pkcs8PrivateBlob)).
    • On macOS or Linux there is no supported API and you have to parse the DER structure yourself, or use a third-party library.
  2. Create a JSON Web Token / Bearer Token. If you use the System.IdentityModel.Tokens.Jwt package from NuGet, this is fairly simple. You will need the Key ID and Team ID from Apple.

public static string CreateToken(ECDsa key, string keyID, string teamID)
{
    var securityKey = new ECDsaSecurityKey(key) { KeyId = keyID };
    var credentials = new SigningCredentials(securityKey, "ES256");

    var descriptor = new SecurityTokenDescriptor
    {
          IssuedAt = DateTime.Now,
          Issuer = teamID,
          SigningCredentials = credentials
    };

    var handler = new JwtSecurityTokenHandler();
    var encodedToken = handler.CreateEncodedJwt(descriptor);
    return encodedToken;
}

  1. Send an HTTP/2 request. This is as normal, but you need to do two extra things:

    1. Set yourRequestMessage.Version to new Version(2, 0) in order to make the request using HTTP/2.
    2. Set yourRequestMessage.Headers.Authorization to new AuthenticationHeaderValue("bearer", token) in order to provide the bearer authentication token / JWT with your request.

    Then just put your JSON into the HTTP request and POST it to the correct URL.

这篇关于如何在C#中实现基于Apple令牌的推送通知(使用p8文件)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆