using LifePayment.Domain.Shared;
|
using Microsoft.AspNetCore.Authentication;
|
using Microsoft.AspNetCore.Http;
|
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Primitives;
|
using System.Security.Authentication;
|
using System.Security.Claims;
|
using System.Text;
|
using System.Text.Encodings.Web;
|
using System.Threading.Tasks;
|
|
namespace LifePayment.Domain
|
{
|
public class WxPayAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions>
|
{
|
private readonly WxPayRsaHelper _wxPayRsaHelper;
|
|
public WxPayAuthenticationHandler(
|
IOptionsMonitor<AuthenticationSchemeOptions> options,
|
ILoggerFactory logger,
|
UrlEncoder encoder,
|
ISystemClock clock,
|
WxPayRsaHelper wxPayRsaHelper) : base(options, logger, encoder, clock)
|
{
|
_wxPayRsaHelper = wxPayRsaHelper;
|
}
|
|
protected async override Task<AuthenticateResult> HandleAuthenticateAsync()
|
{
|
StringValues signature;
|
StringValues wechatpayNonce;
|
StringValues timespan;
|
var exist = Request.Headers.TryGetValue("Wechatpay-Signature", out signature);
|
if (!exist)
|
{
|
return AuthenticateResult.Fail("Wechatpay-Signature 404");
|
}
|
|
var wechatpayNonceExist = Request.Headers.TryGetValue("Wechatpay-Nonce", out wechatpayNonce);
|
if (!wechatpayNonceExist)
|
{
|
return AuthenticateResult.Fail("Wechatpay-Nonce 404");
|
}
|
|
var timespanExist = Request.Headers.TryGetValue("Wechatpay-Timestamp", out timespan);
|
if (!timespanExist)
|
{
|
return AuthenticateResult.Fail("Wechatpay-Timestamp 404");
|
}
|
|
Request.EnableBuffering();
|
var bytes = new byte[Request.ContentLength ?? 0];
|
var bt = 1;
|
while (bt > 0)
|
{
|
bt = await Request.Body.ReadAsync(bytes, 0, (int)(Request.ContentLength ?? 0));
|
}
|
|
var str = Encoding.Default.GetString(bytes);
|
Request.Body.Position = 0;
|
var mySign = BuildAuth(timespan.ToString(), wechatpayNonce.ToString(), str);
|
var check = _wxPayRsaHelper.Verify(mySign, signature.ToString());
|
if (check)
|
{
|
var claimIdentity = new ClaimsIdentity("WxPayIdentity");
|
var principal = new ClaimsPrincipal(claimIdentity);
|
return AuthenticateResult.Success(new AuthenticationTicket(principal, WxPaySignAuthenticationDefaults.AuthenticationScheme));
|
}
|
else
|
{
|
return AuthenticateResult.Fail(new AuthenticationException("验签失败"));
|
}
|
}
|
|
private string BuildAuth(string timeSpan, string nonce, string body)
|
{
|
var str = $"{timeSpan}\n{nonce}\n{body}\n";
|
return str;
|
}
|
}
|
}
|