Custom AuthorizeFilter: как добавить фильтр для проверки IP-адреса клиента или авторизации на identityserver - PullRequest
1 голос
/ 07 июня 2019

Я занимаюсь разработкой сетевого ядра 2.2. У меня есть авторизация установки через identityserver, и работает нормально. Теперь нравится ставить API-интерфейс за управлением API-интерфейсом Azure, а также добавлять IP-адрес управления API в белый список, поэтому, если запрос поступает от управления API, я не буду авторизовываться через identityserver.

Что мне нравится, так это добавить пользовательский фильтр авторизации, чтобы проверить ip клиента, и если ip действителен, я не буду делать авторизацию через identityserver, но если ip не действителен, я попытаюсь авторизовать через удостоверение личности.

Мне нравится переопределять этот AuthorizeFilter. У кого-нибудь есть советы?

services.AddMvc(options =>
{
    if (!_env.IsUnitTest())
    {
        //Add global filter to make sure we require authenticated users for everything!
       var requireAuthenticatedUsersPolicy =
           new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();
       options.Filters.Add(new AuthorizeFilter(requireAuthenticatedUsersPolicy));
    }
});

Ответы [ 2 ]

1 голос
/ 11 июня 2019

Спасибо! Я получил это работает с добавлением требования и обработчик:

public class IpAddressWhitelistHandler : AuthorizationHandler<IpAddressWhitelistRequirement>
{
    private readonly IHttpContextAccessor _httpAccessor;

    public IpAddressWhitelistHandler(IHttpContextAccessor httpAccessor)
    {
        _httpAccessor = httpAccessor;
    }

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, IpAddressWhitelistRequirement requirement)
    {
        var remoteIp = _httpAccessor.HttpContext.Connection.RemoteIpAddress;
        if (IsIpValid(remoteIp, requirement))
        {
            context.Succeed(requirement);
        }

        else
        {
            if (IsAuthenticated(context.User))
            {
                context.Succeed(requirement);
            }
            else
            {
                context.Fail();
            }
        }

        return Task.CompletedTask;

    }

    private bool IsIpValid(IPAddress ipAddress, IpAddressWhitelistRequirement requirement)
    {
        bool validIp = false;

        var bytes = ipAddress.GetAddressBytes();

        var safeIp = IPAddress.Parse(requirement.IpAddress);
        if (safeIp.GetAddressBytes().SequenceEqual(bytes))
        {
            validIp = true;
        }

        return validIp;
    }

    private bool IsAuthenticated(ClaimsPrincipal user)
    {
        var userIsAnonymous = user?.Identity == null || !user.Identities.Any(i => i.IsAuthenticated);

        return !userIsAnonymous;

    }
}

public class IpAddressWhitelistRequirement : IAuthorizationRequirement
{
    public string IpAddress { get; set; }
}
1 голос
/ 10 июня 2019

Вы можете использовать Фильтры действий для проверки удаленного IP-адреса запросов на конкретные контроллеры или методы действий.Весь пример кода находится в этой статье :

public class ClientIdCheckFilter : ActionFilterAttribute
{
    private readonly ILogger _logger;
    private readonly string _safelist;

    public ClientIdCheckFilter
        (ILoggerFactory loggerFactory, IConfiguration configuration)
    {
        _logger = loggerFactory.CreateLogger("ClientIdCheckFilter");
        _safelist = configuration["AdminSafeList"];
    }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        _logger.LogInformation(
            $"Remote IpAddress: {context.HttpContext.Connection.RemoteIpAddress}");

        var remoteIp = context.HttpContext.Connection.RemoteIpAddress;
        _logger.LogDebug($"Request from Remote IP address: {remoteIp}");

        string[] ip = _safelist.Split(';');

        var bytes = remoteIp.GetAddressBytes();
        var badIp = true;
        foreach (var address in ip)
        {
            var testIp = IPAddress.Parse(address);
            if (testIp.GetAddressBytes().SequenceEqual(bytes))
            {
                badIp = false;
                break;
            }
        }

        if (badIp)
        {
            _logger.LogInformation(
                $"Forbidden Request from Remote IP address: {remoteIp}");
            context.Result = new StatusCodeResult(401);
            return;
        }

        base.OnActionExecuting(context);
    }
}
...