ASP.NET 自定义 WebHook 实现
ASP.NET Custom WebHook implementation
我想为我的 Smoobu 帐户创建一个 webhook 接收器。我创建了一个基于 Web Api 的 Web 应用程序并安装了 Microsoft.AspNet.WebHooks.Receivers.Custom 包。
项目中包含的关键文件及其内容如下:
App_Start\WebApiConfig.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
namespace SmoobuWebHook
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
// Initialize Custom WebHook receiver
config.InitializeReceiveCustomWebHooks();
}
}
}
Web.config
<?xml version="1.0" encoding="utf-8"?>
<!--
For more information on how to configure your ASP.NET application, please visit
https://go.microsoft.com/fwlink/?LinkId=301879
-->
<configuration>
<appSettings>
<add key="MS_WebHookReceiverSecret_Custom" value="12345678901234567890123456789012" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.7.2" />
<httpRuntime targetFramework="4.7.2" />
</system.web>
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" />
<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-5.2.7.0" newVersion="5.2.7.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.7.0" newVersion="5.2.7.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.7.0" newVersion="5.2.7.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<system.codedom>
<compilers>
<compiler extension=".cs" language="c#;cs;csharp" warningLevel="4" compilerOptions="/langversion:7.3 /nowarn:1659;1699;1701;612;618" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=3.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<compiler extension=".vb" language="vb;vbs;visualbasic;vbscript" warningLevel="4" compilerOptions="/langversion:default /nowarn:41008,40000,40008 /define:_MYTYPE=\"Web\" /optionInfer+" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=3.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</compilers>
</system.codedom>
</configuration>
Custom.cs
using Microsoft.AspNet.WebHooks;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Web;
namespace SmoobuWebHook
{
public class CustomWebHookHandler : WebHookHandler
{
public CustomWebHookHandler()
{
this.Receiver = CustomWebHookReceiver.ReceiverName;
}
public override Task ExecuteAsync(string generator, WebHookHandlerContext context)
{
// Get data from WebHook
CustomNotifications data = context.GetDataOrDefault<CustomNotifications>();
// Get data from each notification in this WebHook
foreach (IDictionary<string, object> notification in data.Notifications)
{
Console.WriteLine(notification.ToString());
}
return Task.FromResult(true);
}
}
}
我已经启动了到本地主机的 ngrok 隧道。
我通过 Postman 发送 post 请求,方法是在 header:
中包含 ms-signature 键值
(我计算了 ms-signature (e1b85b27d6bcb05846c18e6a48f118e89f0c0587140de9fb3359f8370d0dba08) 的值 https://xorbin.com/tools/sha256-hash-calculator)
从Postman截图中可以看出,响应信息是“'ms-signature'header字段提供的WebHook签名与'CustomWebHookReceiver'接收方期望的值不匹配。 WebHook 请求无效。”。
此外,webhook 接收器中不会触发 webhook 处理程序。
我的问题:
- 代码有什么问题?
- 有没有不用SECRET实现webhook的方法?问这个是因为在 Smoobu 文档中没有关于 webhook 秘密配置的任何内容所以我怀疑他们是否在他们的 webhook 中提供了秘密 header...
提前致谢。
在 .net 上花费数小时实现 webhook 后,我找到了以下 3-4 行 php 代码并为我工作:
header('Content-Type: application/json');
$request = file_get_contents('php://input');
$req_dump = print_r( $request, true );
$fp = file_put_contents( 'request.log', $req_dump );
您可以随意处理 $req_dump...
我想为我的 Smoobu 帐户创建一个 webhook 接收器。我创建了一个基于 Web Api 的 Web 应用程序并安装了 Microsoft.AspNet.WebHooks.Receivers.Custom 包。
项目中包含的关键文件及其内容如下:
App_Start\WebApiConfig.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
namespace SmoobuWebHook
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
// Initialize Custom WebHook receiver
config.InitializeReceiveCustomWebHooks();
}
}
}
Web.config
<?xml version="1.0" encoding="utf-8"?>
<!--
For more information on how to configure your ASP.NET application, please visit
https://go.microsoft.com/fwlink/?LinkId=301879
-->
<configuration>
<appSettings>
<add key="MS_WebHookReceiverSecret_Custom" value="12345678901234567890123456789012" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.7.2" />
<httpRuntime targetFramework="4.7.2" />
</system.web>
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" />
<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-5.2.7.0" newVersion="5.2.7.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.7.0" newVersion="5.2.7.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.7.0" newVersion="5.2.7.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<system.codedom>
<compilers>
<compiler extension=".cs" language="c#;cs;csharp" warningLevel="4" compilerOptions="/langversion:7.3 /nowarn:1659;1699;1701;612;618" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=3.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<compiler extension=".vb" language="vb;vbs;visualbasic;vbscript" warningLevel="4" compilerOptions="/langversion:default /nowarn:41008,40000,40008 /define:_MYTYPE=\"Web\" /optionInfer+" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=3.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</compilers>
</system.codedom>
</configuration>
Custom.cs
using Microsoft.AspNet.WebHooks;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Web;
namespace SmoobuWebHook
{
public class CustomWebHookHandler : WebHookHandler
{
public CustomWebHookHandler()
{
this.Receiver = CustomWebHookReceiver.ReceiverName;
}
public override Task ExecuteAsync(string generator, WebHookHandlerContext context)
{
// Get data from WebHook
CustomNotifications data = context.GetDataOrDefault<CustomNotifications>();
// Get data from each notification in this WebHook
foreach (IDictionary<string, object> notification in data.Notifications)
{
Console.WriteLine(notification.ToString());
}
return Task.FromResult(true);
}
}
}
我已经启动了到本地主机的 ngrok 隧道。
我通过 Postman 发送 post 请求,方法是在 header:
中包含 ms-signature 键值(我计算了 ms-signature (e1b85b27d6bcb05846c18e6a48f118e89f0c0587140de9fb3359f8370d0dba08) 的值 https://xorbin.com/tools/sha256-hash-calculator)
从Postman截图中可以看出,响应信息是“'ms-signature'header字段提供的WebHook签名与'CustomWebHookReceiver'接收方期望的值不匹配。 WebHook 请求无效。”。 此外,webhook 接收器中不会触发 webhook 处理程序。
我的问题:
- 代码有什么问题?
- 有没有不用SECRET实现webhook的方法?问这个是因为在 Smoobu 文档中没有关于 webhook 秘密配置的任何内容所以我怀疑他们是否在他们的 webhook 中提供了秘密 header...
提前致谢。
在 .net 上花费数小时实现 webhook 后,我找到了以下 3-4 行 php 代码并为我工作:
header('Content-Type: application/json');
$request = file_get_contents('php://input');
$req_dump = print_r( $request, true );
$fp = file_put_contents( 'request.log', $req_dump );
您可以随意处理 $req_dump...