Pie*_*NAY 4 asp.net-core-mvc .net-core asp.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
Run Code Online (Sandbox Code Playgroud)
appsettings.json 中定义的 IP 白名单:
/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
Run Code Online (Sandbox Code Playgroud)
以下是RequireRole我想要实现的具有相应属性的操作示例:
"IpSecurity": {
"Author": "123.456.789.43,123.456.789.44",
"Admin": "123.456.789.42"
}
Run Code Online (Sandbox Code Playgroud)
从启动定义的可注射
[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)
// ...
Run Code Online (Sandbox Code Playgroud)
这听起来是个好主意吗?
我应该为此制定自定义授权策略、中间件和/或过滤器吗?
我将如何实现该RequireRole属性?
这给出了如何实现 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";
}
Run Code Online (Sandbox Code Playgroud)
然后你可以使用
[Authorize(Policy = MachineRole.AdminMachine)]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1608 次 |
| 最近记录: |