Browse Source
refactor(ipregion): Obtain the geographic description from the ip address.pull/1067/head
committed by
GitHub
17 changed files with 251 additions and 112 deletions
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -0,0 +1,25 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFrameworks>netstandard2.0;netstandard2.1;net8.0</TargetFrameworks> |
|||
<Nullable>enable</Nullable> |
|||
<WarningsAsErrors>Nullable</WarningsAsErrors> |
|||
<AssemblyName>LINGYUN.Abp.AuditLogging.IP2Region</AssemblyName> |
|||
<PackageId>LINGYUN.Abp.AuditLogging.IP2Region</PackageId> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<RootNamespace /> |
|||
</PropertyGroup><PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\common\LINGYUN.Abp.IP2Region\LINGYUN.Abp.IP2Region.csproj" /> |
|||
<ProjectReference Include="..\LINGYUN.Abp.AuditLogging\LINGYUN.Abp.AuditLogging.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,26 @@ |
|||
using LINGYUN.Abp.IP2Region; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.DependencyInjection.Extensions; |
|||
using Volo.Abp.Auditing; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.SecurityLog; |
|||
|
|||
namespace LINGYUN.Abp.AuditLogging.IP2Region; |
|||
|
|||
[DependsOn( |
|||
typeof(AbpIP2RegionModule), |
|||
typeof(AbpAuditLoggingModule))] |
|||
public class AbpAuditLoggingIP2RegionModule : AbpModule |
|||
{ |
|||
public override void PostConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
var configuration = context.Services.GetConfiguration(); |
|||
|
|||
Configure<AbpAuditLoggingIP2RegionOptions>(configuration.GetSection("AuditLogging:IP2Region")); |
|||
|
|||
context.Services.Replace( |
|||
ServiceDescriptor.Transient<IAuditingStore, IP2RegionAuditingStore>()); |
|||
context.Services.Replace( |
|||
ServiceDescriptor.Transient<ISecurityLogStore, IP2RegionSecurityLogStore>()); |
|||
} |
|||
} |
|||
@ -0,0 +1,5 @@ |
|||
namespace LINGYUN.Abp.AuditLogging.IP2Region; |
|||
public class AbpAuditLoggingIP2RegionOptions |
|||
{ |
|||
public bool IsEnabled { get; set; } |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
using LINGYUN.Abp.IP2Region; |
|||
using Microsoft.Extensions.Options; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Auditing; |
|||
|
|||
namespace LINGYUN.Abp.AuditLogging.IP2Region; |
|||
public class IP2RegionAuditingStore : AuditingStore |
|||
{ |
|||
private readonly AbpAuditLoggingIP2RegionOptions _options; |
|||
private readonly IIpLocationInfoProvider _ipLocationInfoProvider; |
|||
public IP2RegionAuditingStore( |
|||
IOptionsMonitor<AbpAuditLoggingIP2RegionOptions> options, |
|||
IIpLocationInfoProvider ipLocationInfoProvider, |
|||
IAuditLogManager manager) |
|||
: base(manager) |
|||
{ |
|||
_options = options.CurrentValue; |
|||
_ipLocationInfoProvider = ipLocationInfoProvider; |
|||
} |
|||
|
|||
public async override Task SaveAsync(AuditLogInfo auditInfo) |
|||
{ |
|||
if (_options.IsEnabled && !auditInfo.ClientIpAddress.IsNullOrWhiteSpace()) |
|||
{ |
|||
var locationInfo = await _ipLocationInfoProvider.GetLocationInfoAsync(auditInfo.ClientIpAddress); |
|||
if (locationInfo?.Remarks?.IsNullOrWhiteSpace() == false) |
|||
{ |
|||
auditInfo.ExtraProperties.Add("Location", $"{locationInfo.Remarks}"); |
|||
} |
|||
} |
|||
await base.SaveAsync(auditInfo); |
|||
} |
|||
} |
|||
@ -0,0 +1,36 @@ |
|||
using LINGYUN.Abp.IP2Region; |
|||
using Microsoft.Extensions.Options; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.SecurityLog; |
|||
|
|||
namespace LINGYUN.Abp.AuditLogging.IP2Region; |
|||
|
|||
public class IP2RegionSecurityLogStore : SecurityLogStore |
|||
{ |
|||
private readonly AbpAuditLoggingIP2RegionOptions _options; |
|||
private readonly IIpLocationInfoProvider _ipLocationInfoProvider; |
|||
public IP2RegionSecurityLogStore( |
|||
IOptionsMonitor<AbpAuditLoggingIP2RegionOptions> options, |
|||
IIpLocationInfoProvider ipLocationInfoProvider, |
|||
ISecurityLogManager manager) |
|||
: base(manager) |
|||
{ |
|||
_options = options.CurrentValue; |
|||
_ipLocationInfoProvider = ipLocationInfoProvider; |
|||
} |
|||
|
|||
public async override Task SaveAsync(SecurityLogInfo securityLogInfo) |
|||
{ |
|||
if (_options.IsEnabled && !securityLogInfo.ClientIpAddress.IsNullOrWhiteSpace()) |
|||
{ |
|||
var locationInfo = await _ipLocationInfoProvider.GetLocationInfoAsync(securityLogInfo.ClientIpAddress); |
|||
if (locationInfo?.Remarks?.IsNullOrWhiteSpace() == false) |
|||
{ |
|||
securityLogInfo.ExtraProperties.Add("Location", $"{locationInfo.Remarks}"); |
|||
} |
|||
} |
|||
|
|||
await base.SaveAsync(securityLogInfo); |
|||
} |
|||
} |
|||
@ -0,0 +1,68 @@ |
|||
using IP2Region.Net.Abstractions; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.IP2Region; |
|||
|
|||
public class IP2RegionLocationInfoProvider : IIpLocationInfoProvider |
|||
{ |
|||
protected static readonly LocationInfo? _nullCache = null; |
|||
|
|||
protected ISearcher Searcher { get; } |
|||
public IP2RegionLocationInfoProvider(ISearcher searcher) |
|||
{ |
|||
Searcher = searcher; |
|||
} |
|||
|
|||
public virtual Task<LocationInfo?> GetLocationInfoAsync(string ipAddress) |
|||
{ |
|||
var region = Searcher.Search(ipAddress); |
|||
if (string.IsNullOrWhiteSpace(region)) |
|||
{ |
|||
return Task.FromResult(_nullCache); |
|||
} |
|||
|
|||
var regions = region!.Split('|'); |
|||
// | 0 | 1 | 2 |3| 4 | 5 | 6 |
|
|||
// 39.128.0.0|39.128.31.255|中国|0|云南省|昆明市|移动
|
|||
// regions:
|
|||
// 中国 0 云南省 昆明市 移动
|
|||
var locationInfo = new LocationInfo |
|||
{ |
|||
Country = regions.Length >= 1 && !string.Equals(regions[0], "0") ? regions[0] : null, |
|||
Province = regions.Length >= 3 && !string.Equals(regions[2], "0") ? regions[2] : null, |
|||
City = regions.Length >= 4 && !string.Equals(regions[3], "0") ? regions[3] : null, |
|||
}; |
|||
|
|||
// 36.133.108.0|36.133.119.255|中国|0|重庆|重庆市|移动
|
|||
if (!locationInfo.Province.IsNullOrWhiteSpace() && !locationInfo.City.IsNullOrWhiteSpace()) |
|||
{ |
|||
if (locationInfo.Province.Length < locationInfo.City.Length && |
|||
locationInfo.City.StartsWith(locationInfo.Province, StringComparison.InvariantCultureIgnoreCase)) |
|||
{ |
|||
// 重庆市
|
|||
locationInfo.Remarks = $"{locationInfo.City}"; |
|||
} |
|||
// 111.26.31.0|111.26.31.127|中国|0|吉林省|吉林市|移动
|
|||
else |
|||
{ |
|||
// 吉林省吉林市
|
|||
locationInfo.Remarks = $"{locationInfo.Province}{locationInfo.City}"; |
|||
} |
|||
} |
|||
// 220.246.0.0|220.246.255.255|中国|0|香港|0|电讯盈科
|
|||
else if (!locationInfo.Country.IsNullOrWhiteSpace() && !locationInfo.Province.IsNullOrWhiteSpace()) |
|||
{ |
|||
// 中国香港
|
|||
locationInfo.Remarks = $"{locationInfo.Country}{locationInfo.Province}"; |
|||
} |
|||
// 220.247.4.0|220.247.31.255|日本|0|0|0|0
|
|||
else |
|||
{ |
|||
// 日本
|
|||
locationInfo.Remarks = $"{locationInfo.Country}"; |
|||
} |
|||
|
|||
return Task.FromResult<LocationInfo?>(locationInfo); |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
namespace LINGYUN.Abp.IP2Region; |
|||
public class LocationInfo |
|||
{ |
|||
public string? Country { get; set; } |
|||
public string? Province { get; set; } |
|||
public string? City { get; set; } |
|||
public string? Remarks { get; set; } |
|||
} |
|||
@ -1,48 +1,13 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
|
|||
namespace LINGYUN.Abp.Identity.Session.AspNetCore; |
|||
namespace LINGYUN.Abp.Identity.Session.AspNetCore; |
|||
public class AbpIdentitySessionAspNetCoreOptions |
|||
{ |
|||
/// <summary>
|
|||
/// 是否解析IP地理信息
|
|||
/// </summary>
|
|||
public bool IsParseIpLocation { get; set; } |
|||
/// <summary>
|
|||
/// 不做处理的省份
|
|||
/// </summary>
|
|||
public IList<string> IgnoreProvinces { get; set; } |
|||
/// <summary>
|
|||
/// 地理信息解析
|
|||
/// </summary>
|
|||
public Func<LocationInfo, string> LocationParser { get; set; } |
|||
|
|||
public AbpIdentitySessionAspNetCoreOptions() |
|||
{ |
|||
IsParseIpLocation = false; |
|||
IgnoreProvinces = new List<string> |
|||
{ |
|||
// 中国直辖市不显示省份数据
|
|||
"北京", "上海", "天津", "重庆" |
|||
}; |
|||
LocationParser = (locationInfo) => |
|||
{ |
|||
var location = ""; |
|||
|
|||
if (!locationInfo.Province.IsNullOrWhiteSpace() && |
|||
!IgnoreProvinces.Contains(locationInfo.Province)) |
|||
{ |
|||
location += locationInfo.Province + " "; |
|||
} |
|||
if (!locationInfo.City.IsNullOrWhiteSpace()) |
|||
{ |
|||
location += locationInfo.City; |
|||
} |
|||
if (location.IsNullOrWhiteSpace() && !locationInfo.Country.IsNullOrWhiteSpace()) |
|||
{ |
|||
location = locationInfo.Country; |
|||
} |
|||
return location; |
|||
}; |
|||
} |
|||
} |
|||
|
|||
@ -1,36 +0,0 @@ |
|||
using IP2Region.Net.Abstractions; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace LINGYUN.Abp.Identity.Session.AspNetCore; |
|||
|
|||
public class IP2RegionLocationInfoProvider : IIpLocationInfoProvider |
|||
{ |
|||
protected static readonly LocationInfo _nullCache = null; |
|||
|
|||
protected ISearcher Searcher { get; } |
|||
public IP2RegionLocationInfoProvider(ISearcher searcher) |
|||
{ |
|||
Searcher = searcher; |
|||
} |
|||
|
|||
public virtual Task<LocationInfo> GetLocationInfoAsync(string ipAddress) |
|||
{ |
|||
var region = Searcher.Search(ipAddress); |
|||
if (region.IsNullOrWhiteSpace()) |
|||
{ |
|||
return Task.FromResult(_nullCache); |
|||
} |
|||
|
|||
var regions = region.Split('|'); |
|||
// | 0 | 1 | 2 |3| 4 | 5 | 6 |
|
|||
// 39.128.0.0|39.128.31.255|中国|0|云南省|昆明市|移动
|
|||
var locationInfo = new LocationInfo |
|||
{ |
|||
Country = regions.Length >= 3 && !string.Equals(regions[2], "0") ? regions[2] : null, |
|||
Province = regions.Length >= 5 && !string.Equals(regions[4], "0") ? regions[4] : null, |
|||
City = regions.Length >= 6 && !string.Equals(regions[5], "0") ? regions[5] : null, |
|||
}; |
|||
return Task.FromResult(locationInfo); |
|||
} |
|||
} |
|||
@ -1,7 +0,0 @@ |
|||
namespace LINGYUN.Abp.Identity.Session; |
|||
public class LocationInfo |
|||
{ |
|||
public string Country { get; set; } |
|||
public string Province { get; set; } |
|||
public string City { get; set; } |
|||
} |
|||
@ -1,15 +0,0 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace LINGYUN.Abp.Identity.Session; |
|||
|
|||
[Dependency(ServiceLifetime.Singleton, TryRegister = true)] |
|||
public class NoneIpLocationInfoProvider : IIpLocationInfoProvider |
|||
{ |
|||
protected static readonly LocationInfo _nullCache = null; |
|||
public Task<LocationInfo> GetLocationInfoAsync(string ipAddress) |
|||
{ |
|||
return Task.FromResult(_nullCache); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue