asp.net-core - 基于 IP 的属性授权策略

标签 asp.net-core asp.net-core-mvc .net-core

我正在尝试根据客户端 IP 保护 REST API 的安全。

想象一个带有这些请求示例的博客应用程序:

/post/list               // Everyone     should see the posts
/post/create             // Only Authors should create a post
/post/update/42          // Only Authors should update a post
/post/delete/42          // Only Admins  should delete a post
/comment/42/list         // Everyone     should see a post's comments
/comment/42/create       // Everyone     should create a comment
/comment/42/delete/1337  // Only Admins  should delete a comment

appsettings.json 中定义的 IP 白名单:

"IpSecurity": {
  "Author": "123.456.789.43,123.456.789.44",
  "Admin": "123.456.789.42"
}

以下是我想要实现的带有相应 RequireRole 属性的操作示例:

[HttpGet("post/list")]
public List<Post> List()
// ...

[RequireRole("Author")]
[HttpGet("post/create")]
public StandardResponse Create([FromBody]Post post)
// ...

[RequireRole("Admin")]
[HttpGet("post/delete/{id}")]
public StandardResponse Delete(int id)
// ...

启动定义可注入(inject)

var IpSecurity = Configuration.GetSection("IpSecurity");
services.Configure<IpSecurityConfig>(IpSecurity);

这听起来是个好主意吗?

我应该为此制定自定义授权策略、中间件和/或过滤器吗?

如何实现 RequireRole 属性?

<小时/>

This 提供了如何实现 IP 白名单的想法,但由于中间件无权访问上下文操作,因此我无法使用属性来定义我的要求。

最佳答案

是的,这看起来不错,尤其是因为它看起来很容易理解。

我要提出的一个评论是,使用“角色”一词可能会让您的继任者感到困惑。称之为“MachineRole”? (并且,出于同样的原因,不要使用 [Authorize(Roles="..."])

在我看来,AspNetCore 中的实现比 MVC4 下的实现要复杂一些,Startup.cs 中的常用方法与此类似:

public void ConfigureServices(IServiceCollection services)
{
    //after services.AddMvc() :

    services.AddAuthorization(o => { o.AddPolicy(MachineRole.AuthorMachine, p => p.RequireClaim(nameof(MachineRole), MachineRole.AuthorMachine));  });
    services.AddAuthorization(o => { o.AddPolicy(MachineRole.AdminMachine,  p => p.RequireClaim(nameof(MachineRole), MachineRole.AdminMachine)); });
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    // ...

    app.UseClaimsTransformation( AddMachineRoleClaims );

    // app.UseMvc( ... );
    // ...etc...
}

public Task<ClaimsPrincipal> AddMachineRoleClaims(ClaimsTransformationContext ctx)
{
    var connectionRemoteIpAddress = ctx.Context.Connection.RemoteIpAddress.MapToIPv4();
    if (Configuration.GetSection("IpSecurity")["Author"].Contains(connectionRemoteIpAddress.ToString()))
    {
        ctx.Principal.AddIdentity(new ClaimsIdentity(new[] { new Claim(nameof(MachineRole), MachineRole.AuthorMachine) }));
    }
    if (Configuration.GetSection("IpSecurity")["Admin"].Contains(connectionRemoteIpAddress.ToString()))
    {
        ctx.Principal.AddIdentity(new ClaimsIdentity(new[] { new Claim( nameof(MachineRole), MachineRole.AdminMachine) }));
    }

    return Task.FromResult(ctx.Principal);
}

public static class MachineRole
{
    public const string AuthorMachine = "AuthorMachine";
    public const string AdminMachine = "AdminMachine";
}

然后你就可以使用

[Authorize(Policy = MachineRole.AdminMachine)]

关于asp.net-core - 基于 IP 的属性授权策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45712647/

相关文章:

asp.net-core - 无法将模式“”中的表“AspNetUsers”用于实体“AspNetUsers”,因为该表正用于另一个实体

c# - 根据操作名称授权用户

c# - Azure 中的 ServiceBusTrigger 函数 CLI?

c# - 如何有条件地删除 Controller 由 ASP.NET Core 注册并添加到 ServiceCollection

c# - ASP.NET:检查是否从迁移运行

c# - HttpClient JsonReaderException 解析值时出现意外字符

c# - 基于路由值的全局资源授权

c# - 具有 DbContext 的单例 - 在 Startup.cs 中创建实例

c# - ServiceFilter 和 TypeFilter - 注入(inject)这些过滤器有什么区别?

.net-core - 从 Electron 应用程序调用 .NET 核心库