我正在开发一个Net Core 2.2 Web API。 我具有通过Identityserver进行的安装授权,并且工作正常。 现在,喜欢将api置于azure api管理之后,并喜欢将api管理ip地址添加到白名单中,因此,如果请求来自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));
}
});
答案 0 :(得分:1)
您可以使用“操作”过滤器来检查特定控制器或操作方法的请求的远程IP地址。整个代码示例位于this article中:
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);
}
}
答案 1 :(得分:1)
谢谢! 我通过添加需求和处理程序来完成此工作:
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; }
}