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
-
Unitree Robotics Founder Wang Xingxing Releases Video Statement: Warning Against Online Misinformation, Protecting Shareholder InterestsDetail
2025-03-02 12:40:18 1
-
The Age of Smart Homes Arrives: Habitat L32 Ushers in an Upgrade to Living ExperienceDetail
2025-02-28 21:16:59 1
-
Alibaba's DAMO Academy Announces Imminent Delivery of XuanTie C930 Processor, Achieving 15/GHz in SPECint2006 BenchmarkDetail
2025-02-28 11:06:08 1
-
China's OTA Platforms: A High-Efficiency Miracle Under Low Commission RatesDetail
2025-02-28 10:38:34 21
-
China Leads in Setting International Standard for Elderly Care Robots, Ushering in a New Era for the Global Silver EconomyDetail
2025-02-28 10:37:23 1
-
Xiaomi SU7 Ultra: The World's Strongest Four-Door Production Car, 10,000 Pre-orders in Two Hours, Price Drop Ignites the Market!Detail
2025-02-28 10:29:25 1
-
Kingdee Qatar Company Established: Empowering Middle Eastern Enterprises' Digital Transformation with Digital Technology, Driving the "National Vision 2030"Detail
2025-02-28 09:56:02 1
- Detail
-
DeepSeek API Price Adjustment: Off-Peak Discounts Reduce Costs, Up to 75% OffDetail
2025-02-27 10:47:53 21
-
Lenovo's Ask Tian AI Computing Platform Receives Major Upgrade, Enabling Single-Machine Deployment of 671B-Parameter DeepSeek-R1 ModelDetail
2025-02-26 15:22:05 1
-
Largest Mesozoic Scorpion Fossil Discovered in China: Jeholialongchengi Fills Fossil GapDetail
2025-02-26 10:35:56 1
-
Haier Smart Home Leads the Globalization of Appliance Services: Unified Standards, Setting a New Benchmark for Digital ServicesDetail
2025-02-25 17:39:01 1
-
Douyin Livestreaming Shops: A New Engine Driving the Digital Transformation of the Real EconomyDetail
2025-02-25 17:38:14 21
-
Zhou Hongyi, founder of 360 Group, and Nano AI Search's New Energy Vehicle Giveaway Event Concludes Successfully, Marking a Step Forward in AI PopularizationDetail
2025-02-24 18:36:23 31
-
Leaked CAD Renderings Reveal iPhone 17 Series: Two-Tone Back and Novel Camera Designs Spark InterestDetail
2025-02-24 17:27:08 1
-
Yadea Unveils the Modern Series: High-Style Design Meets Tenfold Safety, Ushering in a New Era of Women's CommuteDetail
2025-02-24 14:34:28 1
-
IBM's mandatory return-to-office policy sparks controversy: disguised layoffs, unfair to employees?Detail
2025-02-24 14:15:41 1
-
Apple Halts iCloud Advanced Data Protection in UK: A Stand Against Government 'Backdoor' DemandsDetail
2025-02-24 14:10:40 31
-
S&P Global Sustainability Yearbook 2024: Baidu's Inclusion Highlights the Crucial Role of AI GovernanceDetail
2025-02-19 21:08:50 1
-
Ronshen Refrigerators Lead 2024 Offline Market: Full-Scenario Embedded Refrigerators Drive Consumption UpgradeDetail
2025-02-19 19:12:01 11