lingling
2025-04-16 d0558ff1687a1bffd62c45660d4bab3132643039
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
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;
        }
    }
}