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
-
The 2025 Chinese New Year (Spring Festival) film box office has exploded, exceeding 3 billion RMB and setting a new record for presales!Detail
2025-01-29 11:55:06 1
-
Seres and Beihang University Join Hands to Build an Innovative Ecosystem, Deepening Industry-Academia-Research Collaboration and Promoting Technological TransformationDetail
2025-01-28 14:46:18 1
-
Douyin 2024 Platform Governance Report: Safeguarding Security, Building a Better CommunityDetail
2025-01-28 14:25:55 1
-
Chinese Scientists Develop a Lightweight Bionic Dexterous Hand with 19 Degrees of Freedom, Promising to Revolutionize Prosthetic and Robotics TechnologyDetail
2025-01-28 14:16:39 1
-
DeepSeek: A Chinese AI Startup's Meteoric Rise Shakes Up Global Tech and Sends US Stocks PlungingDetail
2025-01-28 14:13:23 1
-
WeChat's New Year's Red Envelope Feature Gets a Voice Message Upgrade for Warmer Wishes!Detail
2025-01-26 11:37:36 1
-
360 Digital Security Group and Zhibangyang Education Technology Join Forces to Build a New Ecosystem for Cybersecurity and AI Talent CultivationDetail
2025-01-24 15:09:51 1
-
Visionox Achieves Mass Production of AMOLED with Solid-State Laser Annealing (SLA) Technology, Ushering in a New Era for the Display IndustryDetail
2025-01-24 14:34:23 1
-
Seres at the Davos Forum: The Path to Globalizing New Energy Vehicles Through Cooperation in the Intelligent EraDetail
2025-01-23 13:28:12 1
-
Amazon to Close All French-Speaking Quebec Warehouses, Laying Off Nearly 2,000 EmployeesDetail
2025-01-23 10:51:23 1
-
The official launch of the 2025 Electric Bicycle Trade-in Policy: Upgraded Subsidy Standards, Procedures, and PromotionDetail
2025-01-23 10:48:52 1
-
Xbox Series X|S Officially Supports External Hard Drives Larger Than 16TB: Saying Goodbye to Storage WorriesDetail
2025-01-23 10:39:19 1
-
Leaders from the Beijing Chaoyang District CPPCC Visited Quantum Leap Group, Affirming its Contributions and Future Prospects in the Silver Hair EconomyDetail
2025-01-22 17:06:56 1
-
China's Car Imports Remain Sluggish in 2024: 12% Decline, Sharp Drop in New Energy VehiclesDetail
2025-01-22 11:37:25 1
-
China Railway Group Limited (CRGL) officially debunks "speed-up" ticket booking software: Not a shortcut, but a pathway to riskDetail
2025-01-22 11:36:09 1
-
Dago Bio Completes Over $20 Million A+ Round Funding to Accelerate Novel Molecular Glue Drug DevelopmentDetail
2025-01-22 11:34:05 11
-
Rapid Degradation of Global Lake Submerged Vegetation: Satellite Observations Reveal a Critical Period of Ecosystem ShiftDetail
2025-01-22 11:29:03 1
-
Star Ace Capital Group and Abu Dhabi Investment Office Partner to Build a Global Esports Industry BenchmarkDetail
2025-01-22 11:27:50 1
-
Hisense Television Leads the 100-Inch Large-Screen Market in 2024, Achieving an Unparalleled Industry LegacyDetail
2025-01-22 11:12:49 1
-
WeChat Launches "Gifts" Feature: Streamlining Gift-Giving and Powering Social Commerce GrowthDetail
2025-01-21 16:05:45 1