加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-core – 具有Attributes的基于IP的授权策略

发布时间:2020-12-16 06:40:32 所属栏目:asp.Net 来源:网络整理
导读:我正在尝试基于客户端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 //
我正在尝试基于客户端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)
// ...

从Startup定义注射

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

这听起来像个好主意吗?

我应该为此做一个自定义授权策略,中间件和/或过滤器吗?

我如何实现RequireRole属性?

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

解决方法

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

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

在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,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)]

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读