如何将用于审计目的的 web n 层应用程序中的用户身份从用户界面层传递到数据访问层?

Posted

技术标签:

【中文标题】如何将用于审计目的的 web n 层应用程序中的用户身份从用户界面层传递到数据访问层?【英文标题】:How to pass user identity in a web n-layer application for auditing purposes from the User Interface Layer to the Data Access Layer? 【发布时间】:2018-12-28 14:56:50 【问题描述】:

我已经构建了一个以 n 层架构构建的 Web 应用程序,即 UI、BLL、API (WebAPI)、DAL。我希望通过这种关注点分离来实现对 DAL 的基本审核,即 RowCreatedBy、RowUpdatedBy 等,但是我想找出将用户身份从 UI 层向下传递到我的数据访问层,而不将其作为参数添加到我所有的 crud 调用中。那里的选项是使用 Thread.CurrentPrincipal,但是它可以工作,但问题是我的应用程序托管在具有特定标识集的应用程序池下的 IIS 中。我希望 CurrentUser 在我的所有应用程序层中都可用。请建议最好的方法?

注意:我知道人们可能会问这个问题,但从我看到的其他参考资料来看,没有一个能满足我的情况。

【问题讨论】:

【参考方案1】:

我不能说我的方法是“最好的”,但它适合我。

就我而言,MVC 5 Web 应用程序使用 Microsoft 的身份进行身份验证。我使用三个数据库来分离关注点,

身份(身份验证和授权) 应用程序(所有应用程序数据) Elmah(异常记录)

当应用程序数据库中存储可归属于用户的记录时,将使用 userId(来自 Identity 数据库的 nvarchar(128) Guid 字符串)。

唯一的缺点是,当检索要在客户端显示的记录时,必须将每个用户 ID 的关联名称添加到显示数据中。这很简单,因为我的 MVC 控制器通过直接注入传入 ApplicationUserManager。

在需要用户名的实体框架模型中,我添加了一个带有名称字段的部分类并更新它(如下所示)。如果我使用的是视图模型,则采用相同的方法。

r.WhoSavedName = (from u in _userManager.Users where u.Id == r.WhoSavedId select u.UserName).FirstOrDefault();

【讨论】:

【参考方案2】:

解决此问题的一种方法是将一个类注入到您的逻辑/数据层中,以允许访问当前登录的用户,例如

已声明(可能在数据层):

interface ICurrentUserService 
     Guid GetCurrentUserId();

然后在 web 层实现这个:

class CurrentUserService : ICurrentUserService 
    public Guid GetCurrentUserId() 
        return <<User ID obtained via asp.net identity>>
    

如果这个对象被注入到您的数据层类中,那么您应该能够调用以获取当前用户 id,而无需与实际获取该对象的位置相关联(即不依赖于 System.Web 类)。

【讨论】:

以上是关于如何将用于审计目的的 web n 层应用程序中的用户身份从用户界面层传递到数据访问层?的主要内容,如果未能解决你的问题,请参考以下文章

用于审计跟踪的 Elasticsearch

如何在应用程序范围内创建可访问的上下文对象,以便在数据访问中存储当前用户

AWS SES 审计

Java Web 应用程序中的静态层

如何记录所有 Web 事务 (PHP/Laravel)

在数据层而不是单层应用程序中进行审计