目录

介绍

背景

建议的解决方案:将Logger中的错误日志与发送到应用程序的消息链接起来

可恢复和灾难性错误

管理生产中的灾难性错误

管理开发中的灾难性错误

管理生产中的可恢复错误

管理开发中的可恢复错误

使用代码

兴趣点


  • 下载演示 - 16.3 KB

介绍

报告错误似乎是一项微不足道的任务,但如果您不仔细分析您的系统,您可能会遇到安全问题,或者不向用户和技术服务提供正确的信息来报告和解决问题。在本文中,我们将介绍实际问题,如何在开发和生产的不同阶段对其进行管理,以及对其进行管理的代码命题。

背景

在早期基于服务器代码的WEB API中,向Web发送错误的问题并没有那么复杂。服务器管理对API的请求,当发生错误时,您可以将技术错误信息连同解决该错误的所有信息发送给WEB服务器,而Web服务器仅在浏览器中向用户发送一个友好的信息错误。在这种环境下,你不需要限制你的API向WEB服务器发送的信息量,因为通信只是服务器之间的。假设您的服务位于内网或您使用的是加密协议。

随着基于客户端的Web作为Angular和其他框架的流行,对API服务的调用是直接从浏览器完成的。这意味着,如果您继续以服务器基础WEB类型ASP.NET或NET MVC中使用的相同方式发送错误信息,则错误的技术细节将被潜在黑客以明文形式发现浏览器,无论您使用什么协议来保护信息。这种情况是我们系统中的一个重要安全漏洞。

建议的解决方案:将Logger中的错误日志与发送到应用程序的消息链接起来

一种可能的解决方案是创建一个字段,该字段与友好消息一起发送到浏览器,并将相同的值作为记录信息的一部分存储在日志记录器系统中,这样您就可以在日志记录器中找到有关错误的技术信息。将错误与日志记录器中的记录联系起来可以在没有安全风险的情况下解决问题,为技术服务提供必要的信息以纠正生产中的错误情况。

您可以使用时间戳作为字段来链接要使用的错误和日志记录器系统中的日志。让我们在一个例子中看到这一点(见下图)。

假设在微服务“Users”中引发异常,系统会创建一个时间戳并将技术信息发送到日志记录器系统,同时向客户端浏览器发送相同的时间戳和关于错误的友好信息消息,其中还包括失败服务的名称。用户致电支持中心,并给出带有识别错误的时间戳的错误,支持中心向负责生产错误的开发人员发送电子邮件。开发人员转到“user”微服务日志记录器并查找给定日期时间中的条目,其中包含识别问题所需的所有信息。

可恢复和灾难性错误

其他需要解决的问题是我们将向API客户端发送什么类型的HTTP错误。当错误是灾难性的时,逻辑选择是代码500意味着在调用API时发生了一些不可恢复的事情。在这种情况下,可以轻松选择向浏览器发送与记录的技术错误相关联的友好错误。

如果错误可通过用户可以执行的某些操作恢复,则使用错误类型400,该错误类型可以涵盖数据验证、数据缺失或其他类似错误。通常,错误400应该是不会阻止用户继续或纠正服务响应的错误。在这种情况下发送给用户的错误消息应该能够向最终用户解释会发生什么以及可以采取什么措施来避免它。让我们看看生产和开发人员条件中的错误。

管理生产中的灾难性错误

生产中未恢复的错误应该只报告发生了灾难性错误,原因有二:一是出于安全考虑,二是用户无法采取任何措施来解决错误。我们可以做的是向用户发送一个带有时间戳的友好错误,并将技术问题发送给具有相同时间戳的日志记录器系统。发送给用户的友好错误应该通过时间戳与日志记录器条目相关联,便于在日志记录器上定位错误的相关技术条目。

管理开发中的灾难性错误

在开发的情况下,我们可以简单地将技术错误发送到浏览器,因为只有开发团队和可能的QA团队才能看到信息。此外,我们还需要将错误发送到日志记录器系统,并维护发送到浏览器的错误与日志条目之间的关系。

管理生产中的可恢复错误

在可恢复错误的情况下,我们可以将信息发送给允许他/她从错误中恢复的信息。例如,在验证错误的情况下:更改错误名称或填写缺失字段。

在生产中记录此错误的决定可以是可选的,您可以选择记录该类型的错误,在这种情况下,建议将错误级别移至此类型WARN或INFO允许ERROR仅过滤灾难性信息的错误。

管理开发中的可恢复错误

在开发环境和验证错误的情况下,我们继续类似于生产向客户端发送所有可能的信息给客户端。但是我们建议在日志记录器系统中记录这些信息。这在开发过程中解决问题很重要,因为对API的请求不好。

使用代码

在本文中,我们提出了一个对象,它允许我们管理此处讨论的所有不同类型的错误。为此,我们使用以下类:

/// <summary>
/// Error Message
/// </summary>
public class ErrorManager : IErrorManager
{/// <summary>/// This link the log record with the error/// message/// </summary>public DateTime DateCreated { get; set; }/// <summary>/// List of Validations or internal Errors/// Used to reported error conditions that does/// not raise exceptions. Normally Error 400 Type/// </summary>public List<ErrorResponse> Errors { get; set; }/// <summary>/// Friendly description, Reserved for/// Exceptions raised Errors type 500/// </summary>public string Description { get; set; }/// <summary>/// This is the technological Error, should only be/// used in non production environment./// Must be empty in production/// </summary>public Exception DebugException { get; set; }/// <summary>/// Return a initializated error Manager/// </summary>/// <returns></returns>public static IErrorManager Factory(){IErrorManager manager = new ErrorManager();manager.Errors = new List<ErrorResponse>();return manager;}
}

并保存错误响应列表,以下类:

/// <summary>
/// Hold error information only for the developer
/// or technical service
/// </summary>
public class ErrorResponse
{/// <summary>/// Can be a numeric code/// </summary>public string Code { get; set; }/// <summary>/// Description of the error, can be a/// portion of the stack trace./// </summary>public string Description { get; set; }
}

正如您在此对象中每个属性的注释中看到的那样,您可以将所有用于错误类型400或500的信息放在您的web.xml文件中。处于生产或开发阶段。您唯一需要考虑的是根据实验的错误使用属性。

此类应与日志记录器系统一起使用,以允许将记录的错误与发送给用户的信息连接起来。

现在让我们看看如何使用此类来管理.NET Core 3.1 应用程序中的一般错误。下一个代码片段解释了如何在startup.cs文件中的应用程序的一般错误句柄中配置要使用的类。

/// <summary>
/// This method gets called by the runtime.
/// Use this method to configure the HTTP request pipeline.
/// </summary>
/// <param name="app"></param>
/// <param name="env"></param>public void Configure(IApplicationBuilder app, IWebHostEnvironment env){if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}// General Manager for Exceptionsapp.UseExceptionHandler(errorApp =>{errorApp.Run(async context =>{var errorFeature = context.Features.Get<IExceptionHandlerFeature>();DateTime errorReportedtime = DateTime.UtcNow;ErrorManager errorManager = new ErrorManager(){DateCreated = errorReportedtime,};if (!env.IsProduction()){errorManager.DebugException = errorFeature.Error;errorManager.Description = errorFeature.Error.Message;}else{// ProductionerrorManager.Description = $" {errorManager.DateCreated}: Please call our service that a error happen in NetCoreDemo";}// Call the Logger to enter the information   // TODO: Process the information to the logger using the errorManager// TODO: Enter the information in the Logger included in the errorReportedTime// Send the response backvar content = JsonConvert.SerializeObject(errorManager);context.Response.StatusCode = 500; // 500 reserved for exceptions in app.await context.Response.WriteAsync(content);});});app.UseHttpsRedirection();app.UseRouting();// continue the code for other configurations....    }  

观察代码管理与其他环境不同的生产,在生产的情况下,只有带有TimeStamp的通用错误被发送到浏览器。在其他环境的情况下,会向用户发送大量错误报告。

在这两种情况下,广泛的技术信息应存储在Logger中,并且日志记录器应使用时间戳与发送到浏览器客户端的消息链接。

此处的其余代码是获取对象并使用上下文响应对象返回它。

在错误400的情况下,您可以使用请求管道中的验证,并将相同的对象,不同的配置发送到客户端浏览器。执行此操作的代码如下:

/// <summary>/// This method gets called by the runtime./// Use this method to add services to the container./// </summary>/// <param name="services"></param>public void ConfigureServices(IServiceCollection services){services.AddControllers()// Resolving the 400 Validation Error Type.ConfigureApiBehaviorOptions(options =>{options.InvalidModelStateResponseFactory = context =>{IErrorManager errorManager = ErrorManager.Factory();StringBuilder messageb = new StringBuilder();foreach (var item in context.ModelState){messageb.Append($"Validation Failure in{context.ActionDescriptor.DisplayName}Parameter: {item.Key} Error: ");foreach (var i in item.Value.Errors){messageb.Append($" {i.ErrorMessage} - ");}errorManager.Errors.Add(new ErrorResponse(){Code = "400",Description = messageb.ToString()});}// Enter the data timeDateTime errorTime = DateTime.UtcNow;errorManager.DateCreated = errorTime;errorManager.Description =$"{errorTime}: Validation Error in NetCoreDemo";// Call the Logger to enter the information// TODO: Process the information to the logger using the errorManager// TODO: Enter the information in the Logger// included in the errorReportedTimevar error = new BadRequestObjectResult(errorManager);return error;};});// Code continue ....
}

在这段代码中,我们使用Errors属性的数组Errors来列出验证模型状态中存在的验证错误。此外,我们在此处提供了错误的描述以及指向要发送到日志记录器系统的相同错误的链接。请注意,在这里,我们为生产和开发环境发送了相同的信息。

这个例子的完整代码可以从这里下载。

兴趣点

  • 您不应该将生产中的技术错误发送到基于浏览器的Web风格的Angular,相反,您应该将错误的技术数据存储在日志记录器系统中,并且只向用户发送友好的错误。
  • 您应该随友好消息一起发送将友好消息与日志记录器系统中存储的信息链接的可能性。
  • 您应该始终使用同一对象来报告所有类型的错误。您应该针对生产和开发环境的情况自定义对象。

Security Concern when reporting Errors in Client base Web Applications - CodeProject

报告客户端Web应用程序中的错误时的安全问题相关推荐

  1. 如何使用recaptcha_在Spring MVC Web应用程序中使用reCaptcha

    如何使用recaptcha CAPTCHA是一个程序,可以生成人类可以通过但计算机程序" 不能 "通过的测试并对其进行评分. 所采取的策略之一是向用户显示具有扭曲文本的图像,并且用 ...

  2. 在Spring MVC Web应用程序中使用reCaptcha

    CAPTCHA是一种程序,可以生成人类可以通过的测试并对其进行评分,而计算机程序" 不能 "通过. 所采取的策略之一是向用户显示具有扭曲文本的图像,并且用户应在输入区域中书写文本. ...

  3. Java嵌入式数据库H2学习总结(二)——在Web应用程序中使用H2数据库

    一.搭建测试环境和项目 1.1.搭建JavaWeb测试项目 创建一个[H2DBTest]JavaWeb项目,找到H2数据库的jar文件,如下图所示: H2数据库就一个jar文件,这个Jar文件里面包含 ...

  4. 在Web应用程序中使用Canvas API

    更多HTML 5文章请查阅HTML 6在线网站http://www.html5online.com.cn 本文概述 本文介绍如何在一个Web应用程序中利用HTML 5中的Canvas API创建.编辑 ...

  5. DotNetCore Web应用程序中的Cookie管理

    原文来自互联网,由长沙DotNET技术社区编译.如译文侵犯您的署名权或版权,请联系小编,小编将在24小时内删除.限于译者的能力有限,个别语句翻译略显生硬,还请见谅. 作者简介:Jon(Jonathan ...

  6. Spring Security并发会话控制示例教程–如何限制Java JEE Web应用程序中的用户会话数...

    如果您不知道, Spring安全性可能会限制用户可以拥有的会话数. 如果要开发Web应用程序,尤其是Java JEE中的安全Web应用程序 ,则必须提出与在线银行门户相似的要求,例如, 每个用户一次只 ...

  7. EE Servlet 3:如何在Web应用程序中设置后端服务

    在Web应用程序中,提供用户界面(UI)通常只是工作的一半. 许多应用程序都有后端服务支持的要求. 后端服务的一些示例是调度程序进程(批处理),侦听队列并在消息进入时作出响应,或者是简单的事情,例如存 ...

  8. 在Spring MVC Web应用程序中添加社交登录:集成测试

    我已经写了关于为使用Spring Social 1.1.0的应用程序编写单元测试的挑战,并为此提供了一种解决方案 . 尽管单元测试很有价值,但是它并不能真正告诉我们我们的应用程序是否正常运行. 这就是 ...

  9. java面试题8 牛客:在Web应用程序中,( )负责将HTTP请求转换为HttpServletRequest对象

    在Web应用程序中,(    )负责将HTTP请求转换为HttpServletRequest对象 A Servlet对象 B HTTP服务器 C Web容器 D JSP网页 首先我们来看看web程序的 ...

最新文章

  1. 【shiro】使用shiro搭建的项目,页面引用js,报错:Uncaught SyntaxError: Unexpected token ...
  2. redis数据持久化到mysql_Redis【数据持久化篇】
  3. Spring 2.X 中AOP的简明教程
  4. 如何找到某个 ABAP structure 某字段的源头来自哪个数据库表
  5. 考研408大纲22年考研
  6. 创建一个超链接,点击这个超链接,显示数据库中的数据信息:MVC模式查询
  7. Unity —Spine动画
  8. Ubuntu14.04 64位 JAVA Eclipse ADT AndroidStudio 安装
  9. dell笔记本电脑驱动_驱动到底是什么?别再用精灵管家无脑装驱动了
  10. centos7虚拟机网桥模式不通_Centos7虚拟机桥接模式
  11. jemalloc 内存管理
  12. GoodERP交付手册:CRM模块交付
  13. 第五人格显示服务器连接失败,第五人格网络连接失败怎么回事
  14. 《苏菲的世界》读书笔记
  15. 硬件十万个为什么——运放篇(三)如何估算多级放大器的频宽
  16. UEFI开发探索98 – 硬盘访问Diskdump
  17. 如何记住OSI七层协议模型,脑洞大开有木有?
  18. 如何比较两个json
  19. 如何设置网络投票制作投票链接售价多少钱平台投票
  20. android图片引导页

热门文章

  1. .net+mysql关闭连接_asp.net连接mysql出现了远程主机强迫关闭了一个现有的连接。!!!...
  2. oracle 08177,Java OracleDatabaseException: ORA-08177: 无法连续访问此事务处理问题解决
  3. 树莓派连接usb手机_树莓派03 - 树莓派的VNC连接
  4. 搞怪又可爱!一组emoji表情
  5. UI设计灵感|不同形式的图标设计
  6. UI登陆页面素材|让设计师在竞争中脱颖而出
  7. 设计师必备,设计导航网站一流设计导航|16map
  8. 电商首焦素材的万能构图模板
  9. 将用户添加到sudoers_Linux系统如何添加普通用户到 sudoers 文件
  10. 佳能2525i扫描驱动_您需要扫描仪整合工具吗?来试试ExactScan Pro for mac