abp_app_service_ip.jpg
在 ABP Framework 审计日志和安全日志中会记录客端IP地址,为了验证是不是框架本身Bug,查看生产环境数据库 AbpSecurityLogs 表中的记录:
abp_security_logs.png
其中 ClientIpAddress 列记录的IP地址是正常的。
接下来,对问题进行分析:
1. 客户端IP怎么在应用层获取?
IP地址信息保存在 HTTP上下文的请求中,所以要获取IP地址信息首先要获取HTTP上下文 HttpContext 。
在 WebForms 和 ASP.NET MVC WEB应用程序中可以直接通过 HttpContextCurrent.Request 获取请求。
示例:在 ASP.NET MVC 中获取 IP 地址信息
varip = HttpContext.Current.Request.UserHostAddress;
在 ASP.NET Core MVC WEB应用程序中以上方式不起作用,需要通过 IHttpContextAccessor 来获取 HTTP上下文。
ABP Framework 基于 .NE Core 构建,所以,在应用层获取客户端IP地址,只需要在应用服务类中的构造函数中注入接口 IHttpContextAccessor ,获取其实例。
示例:在应用服务中获取IP地址信息
usingMicrosoft.AspNetCore.Http;
publicclassIpAddressAppService{
privatereadonlyIHttpContextAccessor httpContextAccessor;
publicIpAddressAppService(IHttpContextAccessor httpContextAccessor)
{
this.httpContextAccessor = httpContextAccessor;
}
publicstringGetClientIpAddress
{
returnhttpContextAccessor.HttpContext?.Connection.RemoteIpAddress.ToString;
}
} 2. 为什么 IHttpContextAccessor 不可用?
在 .NET Core 中使用构造函数注入服务之前,需要先进行服务注册,否则无法获取服务实例。如果 IHttpContextAccessor 不可用,则说明并没有注册该服务。
最简单的方式,直接手动注册。通常是在 启动程序模块定义类中注册,这样除了在应用服务类使用之外,还可以在控制器类中使用。
实例:在启动程序模块类中注册 IHttpContextAccessor 接口
publicclassAppModule: AbpModule
{
publicoverridevoidConfigureServices(ServiceConfigurationContext context)
{
//...
context.Services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>;
}
}
通过以上设置,就可以在构造函数中正常获取 IHttpContextAccessor 服务了。
3. 深入分析 ABP Framework 和 ASP.NET Core 整合
正常情况下,在 ABP Framework 中不需要手动注册 IHttpContextAccessor ,因为在 Volo.Abp.AspNetCore 模块定义类中进行了服务注册:
privatestaticvoidAddAspNetServices(IServiceCollection services)
{
services.AddHttpContextAccessor;
}
AddHttpContextAccessor 是 .NET Core 程序集 Microsoft.AspNetCore.Http.dll 中为 IServiceCollection 提供的一个扩展方法,该扩展方法用来注册 IHttpContextAccessor 服务,查看该方法源码,可以看到其内部实现也是使用上述手动注册代码:
publicstaticIServiceCollection AddHttpContextAccessor( thisIServiceCollection services)
{
ArgumentNullException.ThrowIfNull(services);
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>;
returnservices;
}
所以,如果使用 ABP Framework 则只需要对 Volo.Abp.AspNetCore 模块直接或间接依赖即可。
如果在应用服务层中不能正常使用 IHttpContextAccessor ,请检查在应用程序模块类中是否已经添加对 Volo.Abp.AspNetCore 模块的依赖。
WEB客户端信息提供程序
在 ABP Framework 中定义了 IWebClientInfoProvider 接口,提供获取 IP地址属性 ClientIpAddress 以及 浏览器信息属性 BrowserInfo 。
接口定义和实现代码位于 Volo.Abp.AspNetCore 程序集,默认实现为 HttpContextWebClientInfoProvider ,该实现内部也是通过 IHttpContextAccessor 获取IP地址。
因此, 在需要获取 客户端IP地址和 浏览器信息应该统一使用 IWebClientInfoProvider 接口。
加入我们同样,在 ABP Framework 框架中,审计日志和安全日志等功能统一采用该接口获取IP地址信息:返回搜狐,查看更多
- • 审计日志提供程序 AspNetCoreAuditLogContributor
- • 安全日志管理器 AspNetCoreSecurityLogManager
- 1. 网站: 知识乐 ,基于 ABP Framework 搭建的学习社区,目前上线系列教程和博客频道:
- • 《ABP Framework 极速开发》 [1] 快速入门
- • 《精读 Mastering ABP Framework》 [2] 系统掌握
- • ABP 博客频道 [3] 最新资讯
- 2. QQ群: ABP Framework 研习社 专注 ABP Framework 学习及DDD实施经验分享;示例源码、电子书共享,欢迎加入! qq_abp_club
- 3. 公众号: dotNET兄弟会 专注.Net开源技术及跨平台开发!致力于构建完善的.Net开放技术文库!为.Net爱好者提供学习交流家园! wechat_brother_qrcode
责任编辑: