自定义授权过滤器:如何添加过滤器以检查客户端 ip 或授权给身份服务器



我正在开发一个净核心2.2 web api。 我已通过身份服务器设置授权,并且工作正常。 现在喜欢把 API 放在 azure api 管理后面,喜欢将 api 管理 ip 地址添加到白名单中,所以如果请求来自 api 管理,我不会通过身份服务器授权。

我喜欢的是,添加一个自定义授权过滤器,检查客户端ip,如果ip有效,我不会通过身份服务器进行授权,但如果IP无效,我会尝试通过身份服务器进行授权。

我喜欢覆盖这个授权过滤器。有人有什么提示吗?

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

可以使用操作筛选器检查特定控制器或操作方法的请求的远程 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);
}
}

谢谢! 我通过添加要求和处理程序得到了这个工作:

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

最新更新