我正在尝试根据客户端 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/