Java Microservices WebApi public interface request signature verification
AD |
,API,,,.
,API
,
,
,.
.
header
| header | | |
| AppId | string | Id |
| Ticks | string | 197011UTC |
| RequestId | string | GUID,, |
| Sign| string | , |
- "{AppId}{Ticks}{RequestId}{AppSecret}"
- MD5,MD5HeaderSign
- APP(AppId,AppSecret),
AppId
- AppId,
- ,AppID(,)
- AppId,,
model.AppId = context.Request.Headers["AppId"]; if (String.IsNullOrEmpty(model.AppId)) { await this.ResponseValidFailedAsync(context, 501); return; } var cacheSvc = context.RequestServices.GetRequiredService<IMemoryCache>(); var cacheAppIdKey = $"RequestValidSign:APPID:{model.AppId}"; var curConfig = cacheSvc.GetOrCreate<AppConfigModel>(cacheAppIdKey, (e) => { e.SlidingExpiration = TimeSpan.FromHours(1); var configuration = context.RequestServices.GetRequiredService<IConfiguration>(); var listAppConfig = configuration.GetSection(AppConfigModel.ConfigSectionKey).Get<AppConfigModel[]>(); return listAppConfig.SingleOrDefault(x => x.AppId == model.AppId); }); if (curConfig == null) { await this.ResponseValidFailedAsync(context, 502); return; }
- (5)
- 197011UTC
var ticksString = context.Request.Headers["Ticks"].ToString(); if (String.IsNullOrEmpty(ticksString)) { await this.ResponseValidFailedAsync(context, 503); return; } model.Ticks = long.Parse(context.Request.Headers["Ticks"].ToString()); var diffTime = DateTime.UtcNow - (new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(model.Ticks)); var expirTime = TimeSpan.FromSeconds(300);// if (diffTime > expirTime) { await this.ResponseValidFailedAsync(context, 504); return; }
ID
- ID
- ID
- IDID
model.RequestId = context.Request.Headers["RequestId"]; if (String.IsNullOrEmpty(model.RequestId)) { await this.ResponseValidFailedAsync(context, 505); return; } var cacheKey = $"RequestValidSign:RequestId:{model.AppId}:{model.RequestId}"; if (cacheSvc.TryGetValue(cacheKey, out _)) { await this.ResponseValidFailedAsync(context, 506); return; } else cacheSvc.Set(cacheKey, model.RequestId, expirTime);
1.
2.$"{AppId}{Ticks}{RequestId}{AppSecret}"
3.MD5Sign
4.
public bool Valid() { var validStr = $"{AppId}{Ticks}{RequestId}{AppSecret}"; return validStr.ToMD5String() == Sign; } model.Sign = context.Request.Headers["Sign"]; if (!model.Valid()) { await this.ResponseValidFailedAsync(context, 507); return; }
Asp.Net Core
/// <summary>/// /// </summary>public class RequestValidSignMiddleware{ private readonly RequestDelegate _next; public RequestValidSignMiddleware(RequestDelegate next) { _next = next; } public async Task InvokeAsync(HttpContext context) { var model = new RequestValidSignModel(); //1.AppId, //2.,AppID(,) //3.AppId,, model.AppId = context.Request.Headers["AppId"]; if (String.IsNullOrEmpty(model.AppId)) { await this.ResponseValidFailedAsync(context, 501); return; } var cacheSvc = context.RequestServices.GetRequiredService<IMemoryCache>(); var cacheAppIdKey = $"RequestValidSign:APPID:{model.AppId}"; var curConfig = cacheSvc.GetOrCreate<AppConfigModel>(cacheAppIdKey, (e) => { e.SlidingExpiration = TimeSpan.FromHours(1); var configuration = context.RequestServices.GetRequiredService<IConfiguration>(); var listAppConfig = configuration.GetSection(AppConfigModel.ConfigSectionKey).Get<AppConfigModel[]>(); return listAppConfig.SingleOrDefault(x => x.AppId == model.AppId); }); if (curConfig == null) { await this.ResponseValidFailedAsync(context, 502); return; } //1./APP,AppSecret //2.AppSecret(),AppSecret //3.AppSecretBase64 //4.AppSecretAppSecret,, //5.AppSecret,. model.AppSecret = curConfig.AppSecret; var headerSecret = context.Request.Headers["AppSecret"].ToString(); if (!String.IsNullOrEmpty(headerSecret)) { var secretBuffer = new byte[1024]; var secretIsBase64 = Convert.TryFromBase64String(headerSecret, new Span<byte>(secretBuffer), out var bytesWritten); if (secretIsBase64 && Encoding.UTF8.GetString(secretBuffer, 0, bytesWritten) == curConfig.AppSecret) await _next(context); else { await this.ResponseValidFailedAsync(context, 508); return; } } else { //1. //2.(5) //197011UTC var ticksString = context.Request.Headers["Ticks"].ToString(); if (String.IsNullOrEmpty(ticksString)) { await this.ResponseValidFailedAsync(context, 503); return; } model.Ticks = long.Parse(context.Request.Headers["Ticks"].ToString()); var diffTime = DateTime.UtcNow - (new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(model.Ticks)); var expirTime = TimeSpan.FromSeconds(300);// if (diffTime > expirTime) { await this.ResponseValidFailedAsync(context, 504); return; } //1.ID //2.ID //3.IDID model.RequestId = context.Request.Headers["RequestId"]; if (String.IsNullOrEmpty(model.RequestId)) { await this.ResponseValidFailedAsync(context, 505); return; } var cacheKey = $"RequestValidSign:RequestId:{model.AppId}:{model.RequestId}"; if (cacheSvc.TryGetValue(cacheKey, out _)) { await this.ResponseValidFailedAsync(context, 506); return; } else cacheSvc.Set(cacheKey, model.RequestId, expirTime); //1. //2.$"{AppId}{Ticks}{RequestId}{AppSecret}" //3.MD5Sign //4. model.Sign = context.Request.Headers["Sign"]; if (!model.Valid()) { await this.ResponseValidFailedAsync(context, 507); return; } await _next(context); } } /// <summary> /// /// </summary> /// <param name="context"></param> /// <param name="status"></param> /// <returns></returns> public async Task ResponseValidFailedAsync(HttpContext context, int status) { context.Response.StatusCode = 500; await context.Response.WriteAsJsonAsync(new ComResult() { Success = false, Status = status, Msg = "" }, Extention.DefaultJsonSerializerOptions, context.RequestAborted); }}public class AppConfigModel{ public const string ConfigSectionKey = "AppConfig"; /// <summary> /// Id /// </summary> public string AppId { get; set; } /// <summary> /// /// </summary> public string AppSecret { get; set; }}public class RequestValidSignModel : AppConfigModel{ /// <summary> /// /// Date.now() /// 1970 1 1 00:00:00 (UTC) /// </summary> public long Ticks { get; set; } /// <summary> /// ID /// </summary> public string RequestId { get; set; } /// <summary> /// /// </summary> public string Sign { get; set; } public bool Valid() { var validStr = $"{AppId}{Ticks}{RequestId}{AppSecret}"; return validStr.ToMD5String() == Sign; }}
,Program/
/// <summary>/// /// </summary>public static class RequestValidSignMiddlewareExtensions{ public static IApplicationBuilder UseRequestValidSign(this IApplicationBuilder builder) { return builder.UseMiddleware<RequestValidSignMiddleware>(); }}///Program.csapp.UseRequestValidSign();
Swagger
Swagger
Header,Header
/// <summary>/// Swagger/// </summary>public class RequestValidSignSwaggerOperationFilter : IOperationFilter{ public void Apply(OpenApiOperation operation, OperationFilterContext context) { if (operation.Parameters == null) operation.Parameters = new List<OpenApiParameter>(); operation.Parameters.Add(new OpenApiParameter { Name = "AppId", In = ParameterLocation.Header, Required = true, Description = "ID", Schema = new OpenApiSchema { Type = "string" } }); operation.Parameters.Add(new OpenApiParameter { Name = "Ticks", In = ParameterLocation.Header, Required = true, Description = "", Example = new OpenApiString(((long)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds).ToString()), Schema = new OpenApiSchema { Type = "string" } }); operation.Parameters.Add(new OpenApiParameter { Name = "RequestId", In = ParameterLocation.Header, Required = true, Description = "ID", Example = new OpenApiString(Guid.NewGuid().ToString()), Schema = new OpenApiSchema { Type = "string" } }); operation.Parameters.Add(new OpenApiParameter { Name = "Sign", In = ParameterLocation.Header, Required = true, Description = "", //{AppId}{Ticks}{RequestId}{AppSecret} Example = new OpenApiString("MD5({AppId}{Ticks}{RequestId}{AppSecret})"), Schema = new OpenApiSchema { Type = "string" } }); operation.Parameters.Add(new OpenApiParameter { Name = "AppSecret", In = ParameterLocation.Header, Description = "()", Example = new OpenApiString("BASE64({AppSecret})"), Schema = new OpenApiSchema { Type = "string" } }); }}///Program.csSwaggerHeaderbuilder.Services.AddSwaggerGen(c =>{ c.OperationFilter<RequestValidSignSwaggerOperationFilter>();});
HttpClient,
,AppId,Ticks,RequestId,Sign
public async Task<string> GetIPAsync(CancellationToken token) { this.SetSignHeader(); var result = await Client.GetStringAsync("/Get", token); return result; } public void SetSignHeader() { this.Client.DefaultRequestHeaders.Clear(); var ticks = ((long)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds).ToString(); var requestId = Guid.NewGuid().ToString(); var signString = $"{this.Config.AppId}{ticks}{requestId}{this.Config.AppSecret}"; var sign = this.GetMD5(signString); this.Client.DefaultRequestHeaders.Add("AppId", this.Config.AppId); this.Client.DefaultRequestHeaders.Add("Ticks", ticks); this.Client.DefaultRequestHeaders.Add("RequestId", requestId); this.Client.DefaultRequestHeaders.Add("Sign", sign); } public string GetMD5(string value) { using (MD5 md5 = MD5.Create()) { byte[] inputBytes = Encoding.UTF8.GetBytes(value); byte[] hashBytes = md5.ComputeHash(inputBytes); StringBuilder sb = new StringBuilder(); for (int i = 0; i < hashBytes.Length; i++) { sb.Append(hashBytes[i].ToString("x2")); } return sb.ToString(); } }
,
,
,
Disclaimer: The content of this article is sourced from the internet. The copyright of the text, images, and other materials belongs to the original author. The platform reprints the materials for the purpose of conveying more information. The content of the article is for reference and learning only, and should not be used for commercial purposes. If it infringes on your legitimate rights and interests, please contact us promptly and we will handle it as soon as possible! We respect copyright and are committed to protecting it. Thank you for sharing.(Email:[email protected])
Mobile advertising space rental |
Tag: Java Microservices WebApi public interface request signature verification
Astronauts are not afraid of sacrifice. Why are they afraid when observing Terrestrial Time on the moon?
NextHow to choose Huawei phones, with 4 price ranges ranging from entry-level to high-end. After reading, you will understand
Guess you like
-
Apple Phones Banned: Why Has the Once-Shining Star Fallen From Grace?Detail
2024-10-01 12:19:49 1
-
AI Audio Incident: Hefei Police Unravel the Truth Behind Online Rumors, A Clash of Technology and JusticeDetail
2024-09-30 22:45:17 1
-
Yadea Guaneng E8: The "Rolls Royce" of Electric Vehicles, A Perfect Blend of Performance and IntelligenceDetail
2024-09-30 22:05:41 1
-
The Chaos of Live Streaming E-commerce: Deep Reflections Triggered by the San Zhi Yang False Advertising IncidentDetail
2024-09-30 19:43:26 1
-
New E-commerce Development Trends: Regulation and Empowerment, Boosting High-Quality Development of the Digital EconomyDetail
2024-09-29 18:03:14 1
- Detail
- Detail
-
Maoyan Entertainment Unveils "Shenbi Malia": AI-Powered Screenplay Creation with One-Click Dynamic Storyboard GenerationDetail
2024-09-27 15:52:43 1
-
Huawei Cloud and CAICT Jointly Released Two Value Reports to Empower City Digital Transformation and UpgradingDetail
2024-09-27 15:29:32 1
-
Huawei MateXT: Scalpers Caught in the Crossfire, High Prices Unrelenting, Can Production Ramp-Up Offer Relief?Detail
2024-09-27 14:40:15 11
-
10G-PON Leads Digital Transformation: 2024 International Information and Communication Exhibition Focuses on Innovative DevelopmentDetail
2024-09-27 14:00:08 1
-
The Light of Science Illuminates Dreams: The Path of Science Popularization at the Shandong Science and Technology MuseumDetail
2024-09-27 11:59:09 11
-
The Huawei Chip Dispute: A Balancing Act Between Independent Innovation and Open CollaborationDetail
2024-09-27 09:34:01 11
-
"Playing it Safe": Li Pao'er's Exit from Sanzhiyang, the Dilemma of "Siege" in Internet Celebrity EconomyDetail
2024-09-27 09:31:55 1
- Detail
-
From "Catching Up" to "Surpassing": The "Golden Age" of China's Precision Instrument DevelopmentDetail
2024-09-25 14:16:48 1
-
Huawei's "Closedness" and "Science": A Debate About the Direction of Technological DevelopmentDetail
2024-09-25 13:43:01 11
- Detail
- Detail
-
2024 National Day (Golden Week) Travel Guide: Amap Predicts Congested Roads, New V15 Version Helps You Say "ByeBye" to TroublesDetail
2024-09-24 14:38:15 11