有条件地忽略授权 .NET Core 3.1
Conditionally Ignore Authorize .NET Core 3.1
我正在将 Web API 从 .net Framework 迁移到 .net Core。如果应用程序 运行 在私有服务器上,旧版本能够忽略控制器上的授权属性。这是它的代码。 我知道 .net core 3.1 不提供自定义 AuthorizeAttributes。那不是我的问题。
// A custom AuthroizeAttribute
public class ConditionalAuthorizeAttribute : AuthorizeAttribute
{
protected override bool IsAuthorized(HttpActionContext httpContext)
{
if (environment_private())
return true;
else
return base.IsAuthorized(httpContext);
}
private bool environment_private()
{
// code that will tell you if you are in your dev environment or not
return Properties.Settings.Default.PrivateServer;
}
}
// How it was called from the controller
[ConditionalAuthorize(Roles = "MyRole")]
[Route(...)]
// More code for controller
我只需要一种简单的方法来授权当 运行 我们私人服务器上的项目(由 appSettings.json 中的变量确定)时的所有请求。我尝试过政策,但我面临以下困难:
1) 我无法将配置中的变量从控制器传递到参数化授权属性。
2) 我无法将配置注入参数化授权属性。
这有效地消除了我以任何方式遵循本指南的能力:https://docs.microsoft.com/en-us/aspnet/core/security/authorization/iauthorizationpolicyprovider?view=aspnetcore-2.2
这引出了我的问题:如何使用 appSettings.json 中的值来覆盖请求是否检查角色?
经过大量研究,我找到了一种使用 TypeFilterAttribute
的方法。本质上,除了我使用 .net Core 支持的方法外,它的实现方式相同(使用自定义属性过滤所有请求并检查自定义属性中的条件)。
如果您正在尝试解决同样的问题,这里是我的解决方案的具体步骤。
- 添加两个文件,"YourAttributeNameAttribute.cs" 和 "YourFilterNameFilter.cs"。
- 在"YourAttributeNameAttribute.cs"文件中,代码如下:
public class YourAttributeNameAttribute : TypeFilterAttribute
{
public YourAttributeNameAttribute(string role) : base(typeof(YourFilterNameFilter))
{
Arguments = new object[] { role };
}
}
- "YourFilterNameFilter.cs"中的代码:
public class YourFilterNameFilter : IAuthorizationFilter
{
private readonly string Role;
public YourFilterNameFilter(string role)
{
Role = role;
}
public void OnAuthorization(AuthorizationFilterContext context)
{
var configuration = context.HttpContext.RequestServices.GetService<IConfiguration>();
// If private server, ignore roles
if (private_server_logic_here)
return;
var user = context.HttpContext.User;
// Check role if on public server
if (!user.IsInRole(Role))
{
context.Result = new StatusCodeResult((int)System.Net.HttpStatusCode.Unauthorized);
return;
}
}
}
- 控制器代码:
[YourAttributeName("role_name")]
[Route("api/my_route")]
[HttpGet]
我正在将 Web API 从 .net Framework 迁移到 .net Core。如果应用程序 运行 在私有服务器上,旧版本能够忽略控制器上的授权属性。这是它的代码。 我知道 .net core 3.1 不提供自定义 AuthorizeAttributes。那不是我的问题。
// A custom AuthroizeAttribute
public class ConditionalAuthorizeAttribute : AuthorizeAttribute
{
protected override bool IsAuthorized(HttpActionContext httpContext)
{
if (environment_private())
return true;
else
return base.IsAuthorized(httpContext);
}
private bool environment_private()
{
// code that will tell you if you are in your dev environment or not
return Properties.Settings.Default.PrivateServer;
}
}
// How it was called from the controller
[ConditionalAuthorize(Roles = "MyRole")]
[Route(...)]
// More code for controller
我只需要一种简单的方法来授权当 运行 我们私人服务器上的项目(由 appSettings.json 中的变量确定)时的所有请求。我尝试过政策,但我面临以下困难:
1) 我无法将配置中的变量从控制器传递到参数化授权属性。
2) 我无法将配置注入参数化授权属性。
这有效地消除了我以任何方式遵循本指南的能力:https://docs.microsoft.com/en-us/aspnet/core/security/authorization/iauthorizationpolicyprovider?view=aspnetcore-2.2
这引出了我的问题:如何使用 appSettings.json 中的值来覆盖请求是否检查角色?
经过大量研究,我找到了一种使用 TypeFilterAttribute
的方法。本质上,除了我使用 .net Core 支持的方法外,它的实现方式相同(使用自定义属性过滤所有请求并检查自定义属性中的条件)。
如果您正在尝试解决同样的问题,这里是我的解决方案的具体步骤。
- 添加两个文件,"YourAttributeNameAttribute.cs" 和 "YourFilterNameFilter.cs"。
- 在"YourAttributeNameAttribute.cs"文件中,代码如下:
public class YourAttributeNameAttribute : TypeFilterAttribute
{
public YourAttributeNameAttribute(string role) : base(typeof(YourFilterNameFilter))
{
Arguments = new object[] { role };
}
}
- "YourFilterNameFilter.cs"中的代码:
public class YourFilterNameFilter : IAuthorizationFilter
{
private readonly string Role;
public YourFilterNameFilter(string role)
{
Role = role;
}
public void OnAuthorization(AuthorizationFilterContext context)
{
var configuration = context.HttpContext.RequestServices.GetService<IConfiguration>();
// If private server, ignore roles
if (private_server_logic_here)
return;
var user = context.HttpContext.User;
// Check role if on public server
if (!user.IsInRole(Role))
{
context.Result = new StatusCodeResult((int)System.Net.HttpStatusCode.Unauthorized);
return;
}
}
}
- 控制器代码:
[YourAttributeName("role_name")]
[Route("api/my_route")]
[HttpGet]