zhengyuxuan
2025-04-02 dbf044662b9a75e5b42f8f76c65faaf89c95bb21
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
using Alipay.AopSdk.Core.Util;
using Alipay.EasySDK.Kernel;
using LifePayment.Domain.Shared;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Authentication;
using System.Security.Claims;
using System.Text;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
using ZeroD.Util;
 
namespace LifePayment.Domain
{
    public class AliPayAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions>
    {
        private readonly IOptionsMonitor<Config> _optionsMonitor;
        private Config _config;
 
        public AliPayAuthenticationHandler(
               IOptionsMonitor<AuthenticationSchemeOptions> options,
               ILoggerFactory logger,
               UrlEncoder encoder,
               ISystemClock clock,
               IOptionsMonitor<Config> optionsMonitor) : base(options, logger, encoder, clock)
        {
            _optionsMonitor = optionsMonitor;
        }
 
        protected async override Task<AuthenticateResult> HandleAuthenticateAsync()
        {
            string str = string.Empty;
            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));
            }
 
            str = Encoding.Default.GetString(bytes);
            Logger.LogError("信任签回调验签{0}", str);
            Request.Body.Position = 0;
            if (!str.IsNullOrEmpty())
            {
                var endPoint = Request.HttpContext.GetEndpoint();
                if (endPoint?.Metadata.GetMetadata<IAllowAnonymous>() != null)
                {
                    return AuthenticateResult.Success(new AuthenticationTicket(new ClaimsPrincipal(), AliPaySignAuthenticationDefaults.AuthenticationScheme));
                }
 
                StringValues app_id;
                var app_idSuccess = Request.Form.TryGetValue("app_id", out app_id);
                if (!app_idSuccess)
                {
                    return AuthenticateResult.Fail(new AuthenticationException("app_id不可为空"));
                }
 
                StringValues msg_method;
                var msg_methodSuccess = Request.Form.TryGetValue("msg_method", out msg_method);
                if (!msg_methodSuccess)
                {
                    return AuthenticateResult.Fail(new AuthenticationException("msg_method不可为空"));
                }
 
                switch (msg_method)
                {
                    case AliPayEcsignConstant.AliPayEcsignApiMethod.SignorderSigned:
                        _config = _optionsMonitor.Get(AliPayEcsignConstant.OptionsName);
                        break;
                    default:
                        _config = _optionsMonitor.CurrentValue;
                        break;
                }
 
                SortedDictionary<string, string> dic = new SortedDictionary<string, string>();
                Request.Form.ToList().ForEach(r =>
                {
                    if (!r.Value.FirstOrDefault().IsNullOrEmpty())
                    {
                        dic.Add(r.Key, r.Value);
                    }
                });
 
                Logger.LogError("信任签回调验签2{0}", dic.ObjectToJson());
                bool signVerified = AlipaySignature.RSACheckV1(dic, _config.AlipayPublicKey, "UTF-8", _config.SignType, false);
                if (signVerified)
                {
                    var claimIdentity = new ClaimsIdentity("AliPayIdentity");
                    claimIdentity.AddClaim(new Claim(nameof(app_id), app_id));
                    var principal = new ClaimsPrincipal(claimIdentity);
                    return AuthenticateResult.Success(new AuthenticationTicket(principal, AliPaySignAuthenticationDefaults.AuthenticationScheme));
                }
            }
 
            return AuthenticateResult.Fail(new AuthenticationException("验签失败"));
        }
    }
}