【问题标题】:Authorize application service based on client IP address根据客户端 IP 地址授权应用服务
【发布时间】:2018-02-03 12:24:30
【问题描述】:

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

【问题讨论】:

    标签: c# authorization ip-address interceptor aspnetboilerplate


    【解决方案1】:

    你可以注入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方法。

    【讨论】:

      【解决方案2】:

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

      看看如何实现注入 https://aspnetboilerplate.com/Pages/Documents/Dependency-Injection

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多