Browse Source

Merge pull request #1064 from colinin/ip-region-location

refactor(ipregion): Obtain the geographic description from the ip address.
pull/1067/head
yx lin 1 year ago
committed by GitHub
parent
commit
c1c3077f96
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 13
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.EntityFrameworkCore/LINGYUN/Abp/AuditLogging/EntityFrameworkCore/AbpAuditingMapperProfile.cs
  2. 3
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP2Region/FodyWeavers.xml
  3. 30
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP2Region/FodyWeavers.xsd
  4. 25
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP2Region/LINGYUN.Abp.AuditLogging.IP2Region.csproj
  5. 26
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP2Region/LINGYUN/Abp/AuditLogging/IP2Region/AbpAuditLoggingIP2RegionModule.cs
  6. 5
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP2Region/LINGYUN/Abp/AuditLogging/IP2Region/AbpAuditLoggingIP2RegionOptions.cs
  7. 34
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP2Region/LINGYUN/Abp/AuditLogging/IP2Region/IP2RegionAuditingStore.cs
  8. 36
      aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP2Region/LINGYUN/Abp/AuditLogging/IP2Region/IP2RegionSecurityLogStore.cs
  9. 3
      aspnet-core/framework/common/LINGYUN.Abp.IP2Region/LINGYUN/Abp/IP2Region/AbpIP2RegionModule.cs
  10. 4
      aspnet-core/framework/common/LINGYUN.Abp.IP2Region/LINGYUN/Abp/IP2Region/IIpLocationInfoProvider.cs
  11. 68
      aspnet-core/framework/common/LINGYUN.Abp.IP2Region/LINGYUN/Abp/IP2Region/IP2RegionLocationInfoProvider.cs
  12. 8
      aspnet-core/framework/common/LINGYUN.Abp.IP2Region/LINGYUN/Abp/IP2Region/LocationInfo.cs
  13. 37
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.Session.AspNetCore/LINGYUN/Abp/Identity/Session/AspNetCore/AbpIdentitySessionAspNetCoreOptions.cs
  14. 13
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.Session.AspNetCore/LINGYUN/Abp/Identity/Session/AspNetCore/HttpContextDeviceInfoProvider.cs
  15. 36
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.Session.AspNetCore/LINGYUN/Abp/Identity/Session/AspNetCore/IP2RegionLocationInfoProvider.cs
  16. 7
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.Session/LINGYUN/Abp/Identity/Session/LocationInfo.cs
  17. 15
      aspnet-core/modules/identity/LINGYUN.Abp.Identity.Session/LINGYUN/Abp/Identity/Session/NoneIpLocationInfoProvider.cs

13
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.EntityFrameworkCore/LINGYUN/Abp/AuditLogging/EntityFrameworkCore/AbpAuditingMapperProfile.cs

@ -1,4 +1,5 @@
using AutoMapper;
using Volo.Abp.ObjectExtending;
namespace LINGYUN.Abp.AuditLogging.EntityFrameworkCore;
@ -7,14 +8,16 @@ public class AbpAuditingMapperProfile : Profile
public AbpAuditingMapperProfile()
{
CreateMap<Volo.Abp.AuditLogging.AuditLogAction, LINGYUN.Abp.AuditLogging.AuditLogAction>()
.MapExtraProperties();
.MapExtraProperties(MappingPropertyDefinitionChecks.None);
CreateMap<Volo.Abp.AuditLogging.EntityPropertyChange, LINGYUN.Abp.AuditLogging.EntityPropertyChange>();
CreateMap<Volo.Abp.AuditLogging.EntityChange, LINGYUN.Abp.AuditLogging.EntityChange>()
.MapExtraProperties();
.MapExtraProperties(MappingPropertyDefinitionChecks.None);
CreateMap<Volo.Abp.AuditLogging.AuditLog, LINGYUN.Abp.AuditLogging.AuditLog>()
.MapExtraProperties();
.MapExtraProperties(MappingPropertyDefinitionChecks.None);
CreateMap<Volo.Abp.Identity.IdentitySecurityLog, LINGYUN.Abp.AuditLogging.SecurityLog>()
.MapExtraProperties();
CreateMap<Volo.Abp.AuditLogging.EntityChangeWithUsername, LINGYUN.Abp.AuditLogging.EntityChangeWithUsername>();
CreateMap<Volo.Abp.Identity.IdentitySecurityLog, LINGYUN.Abp.AuditLogging.SecurityLog>(MemberList.Destination)
.MapExtraProperties(MappingPropertyDefinitionChecks.None);
}
}

3
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP2Region/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

30
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP2Region/FodyWeavers.xsd

@ -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>

25
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP2Region/LINGYUN.Abp.AuditLogging.IP2Region.csproj

@ -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>

26
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP2Region/LINGYUN/Abp/AuditLogging/IP2Region/AbpAuditLoggingIP2RegionModule.cs

@ -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>());
}
}

5
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP2Region/LINGYUN/Abp/AuditLogging/IP2Region/AbpAuditLoggingIP2RegionOptions.cs

@ -0,0 +1,5 @@
namespace LINGYUN.Abp.AuditLogging.IP2Region;
public class AbpAuditLoggingIP2RegionOptions
{
public bool IsEnabled { get; set; }
}

34
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP2Region/LINGYUN/Abp/AuditLogging/IP2Region/IP2RegionAuditingStore.cs

@ -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);
}
}

36
aspnet-core/framework/auditing/LINGYUN.Abp.AuditLogging.IP2Region/LINGYUN/Abp/AuditLogging/IP2Region/IP2RegionSecurityLogStore.cs

@ -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);
}
}

3
aspnet-core/framework/common/LINGYUN.Abp.IP2Region/LINGYUN/Abp/IP2Region/AbpIP2RegionModule.cs

@ -1,6 +1,7 @@
using IP2Region.Net.Abstractions;
using IP2Region.Net.XDB;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
@ -24,5 +25,7 @@ public class AbpIP2RegionModule : AbpModule
return searcher;
});
context.Services.TryAddTransient<IIpLocationInfoProvider, IP2RegionLocationInfoProvider>();
}
}

4
aspnet-core/modules/identity/LINGYUN.Abp.Identity.Session/LINGYUN/Abp/Identity/Session/IIpLocationInfoProvider.cs → aspnet-core/framework/common/LINGYUN.Abp.IP2Region/LINGYUN/Abp/IP2Region/IIpLocationInfoProvider.cs

@ -1,6 +1,6 @@
using System.Threading.Tasks;
namespace LINGYUN.Abp.Identity.Session;
namespace LINGYUN.Abp.IP2Region;
public interface IIpLocationInfoProvider
{
/// <summary>
@ -10,5 +10,5 @@ public interface IIpLocationInfoProvider
/// <returns>
/// 如果解析成功返回地理信息,否则返回null
/// </returns>
Task<LocationInfo> GetLocationInfoAsync(string ipAddress);
Task<LocationInfo?> GetLocationInfoAsync(string ipAddress);
}

68
aspnet-core/framework/common/LINGYUN.Abp.IP2Region/LINGYUN/Abp/IP2Region/IP2RegionLocationInfoProvider.cs

@ -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);
}
}

8
aspnet-core/framework/common/LINGYUN.Abp.IP2Region/LINGYUN/Abp/IP2Region/LocationInfo.cs

@ -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; }
}

37
aspnet-core/modules/identity/LINGYUN.Abp.Identity.Session.AspNetCore/LINGYUN/Abp/Identity/Session/AspNetCore/AbpIdentitySessionAspNetCoreOptions.cs

@ -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;
};
}
}

13
aspnet-core/modules/identity/LINGYUN.Abp.Identity.Session.AspNetCore/LINGYUN/Abp/Identity/Session/AspNetCore/HttpContextDeviceInfoProvider.cs

@ -1,4 +1,5 @@
using DeviceDetectorNET;
using LINGYUN.Abp.IP2Region;
using Microsoft.Extensions.Options;
using System;
using System.Threading.Tasks;
@ -51,17 +52,7 @@ public class HttpContextDeviceInfoProvider : IDeviceInfoProvider, ITransientDepe
protected async virtual Task<string> GetRegion(string ipAddress)
{
var locationInfo = await IpLocationInfoProvider.GetLocationInfoAsync(ipAddress);
if (locationInfo == null)
{
return null;
}
if (Options.LocationParser != null)
{
return Options.LocationParser(locationInfo);
}
return null;
return locationInfo?.Remarks;
}
private class BrowserDeviceInfo

36
aspnet-core/modules/identity/LINGYUN.Abp.Identity.Session.AspNetCore/LINGYUN/Abp/Identity/Session/AspNetCore/IP2RegionLocationInfoProvider.cs

@ -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);
}
}

7
aspnet-core/modules/identity/LINGYUN.Abp.Identity.Session/LINGYUN/Abp/Identity/Session/LocationInfo.cs

@ -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; }
}

15
aspnet-core/modules/identity/LINGYUN.Abp.Identity.Session/LINGYUN/Abp/Identity/Session/NoneIpLocationInfoProvider.cs

@ -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…
Cancel
Save