我们在未经许可的情况下实施了一些应用服务方法。我们如何实现基于客户端IP地址的授权来执行方法?
例如,这是GetParsedData
方法:
public GetParsedDataOutput GetParsedData(GetParsedDataInput input)
{
return _cacheManager.GetCache(nameof(GetData)).Get(input.ToString(), () => gpd(input)) as GetParsedDataOutput;
}
我们如何通过IP地址检查用户权限?假设IP地址为192.168.5.2
的客户端被授予执行此方法的权限。
答案 0 :(得分:5)
您可以注入IClientInfoProvider
来获取ClientIpAddress
。
覆盖PermissionChecker
中的IsGrantedAsync
:
public override async Task<bool> IsGrantedAsync(long userId, string permissionName)
{
if (permissionName == MyClientIpAddressPermissionName)
{
return Task.Run(() => { return _clientInfoProvider.ClientIpAddress == "192.168.5.2"; });
}
return await base.IsGrantedAsync(userId, permissionName);
}
用法:
[AbpAuthorize(MyClientIpAddressPermissionName)]
public GetParsedDataOutput GetParsedData(GetParsedDataInput input)
{
// ...
}
由于AbpAuthorize
需要用户,因此您应该使用自定义(i)属性,(ii)拦截器,以及(iii)拦截器注册器。
(i)属性:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class ClientIpAuthorizeAttribute : Attribute
{
public string AllowedIpAddress { get; set; }
}
(ii)拦截器:
internal class ClientIpAuthorizationInterceptor : IInterceptor
{
private readonly IClientInfoProvider _clientInfoProvider;
public ClientIpAuthorizationInterceptor(IClientInfoProvider clientInfoProvider)
{
_clientInfoProvider = clientInfoProvider;
}
public void Intercept(IInvocation invocation)
{
var methodInfo = invocation.MethodInvocationTarget;
var clientIpAuthorizeAttribute = methodInfo.GetCustomAttributes(true).OfType<ClientIpAuthorizeAttribute>().FirstOrDefault()
?? methodInfo.DeclaringType.GetCustomAttributes(true).OfType<ClientIpAuthorizeAttribute>().FirstOrDefault();
if (clientIpAuthorizeAttribute != null &&
clientIpAuthorizeAttribute.AllowedIpAddress != _clientInfoProvider.ClientIpAddress)
{
throw new AbpAuthorizationException();
}
invocation.Proceed();
}
}
(iii)拦截器注册员:
internal static class ClientIpAuthorizationInterceptorRegistrar
{
public static void Initialize(IIocManager iocManager)
{
iocManager.IocContainer.Kernel.ComponentRegistered += (key, handler) =>
{
if (ShouldIntercept(handler.ComponentModel.Implementation))
{
handler.ComponentModel.Interceptors.Add(new InterceptorReference(typeof(ClientIpAuthorizationInterceptor)));
}
};
}
private static bool ShouldIntercept(Type type)
{
if (type.GetTypeInfo().IsDefined(typeof(ClientIpAuthorizeAttribute), true))
{
return true;
}
if (type.GetMethods().Any(m => m.IsDefined(typeof(ClientIpAuthorizeAttribute), true)))
{
return true;
}
return false;
}
}
在您的应用程序模块中初始化注册商:
public override void PreInitialize()
{
ClientIpAuthorizationInterceptorRegistrar.Initialize(IocManager);
}
用法:
[ClientIpAuthorize(AllowedIpAddress = "192.168.5.2")]
public GetParsedDataOutput GetParsedData(GetParsedDataInput input)
{
// ...
}
您应该能够自己扩展它以允许/禁止多个IP地址。
要回退经过身份验证的用户的权限名称,请在属性中将权限名称添加为string
属性。然后在拦截器中注入IAbpSession
和IPermissionChecker
以调用IsGrantedAsync
方法。
答案 1 :(得分:0)
您可以为IApplicationService编写自己的注入服务。在应用程序服务方法执行之前,您可以进行预检查。
了解如何实施注射 https://aspnetboilerplate.com/Pages/Documents/Dependency-Injection