繁体   English   中英

根据客户端IP地址授权应用程序服务

[英]Authorize application service based on client IP address

我们未经许可已实现了一些应用程序服务方法。 如何执行基于客户端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客户端被授予执行该方法的权限。

您可以注入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属性添加。 然后在拦截器中注入IAbpSessionIPermissionChecker以调用IsGrantedAsync方法。

您可以为IApplicationService编写自己的注射器服务。 并且在执行应用程序服务方法之前,您可以进行预检查。

了解如何实施注入https://aspnetboilerplate.com/Pages/Documents/Dependency-Injection

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM