长话短说,是否可以在我的API上放置基于环境的授权属性,以便在开发中关闭授权限制并在生产中重新启用?
我有一个单独的Angular 2项目,我希望将其称为.NET Core API。我们创建了一个单独的项目,因此我们可以在vscode中打开Angular 2项目并调试typescript。完成后,出于安全原因,我们将构建项目并将其放在.NET Core项目中。
我们的问题是,在调试阶段,我们无法连接到API,因为它们是两个独立的项目,而我们的Angular 2项目没有Active Directory。 .NET Core项目当前具有身份验证属性,并且不允许访问API(401)。如果我们能够在开发过程中将其关闭并在生产过程中重新开启,那将是很好的。
我也对如何最好地解决这个问题提出任何其他建议。
[Authorize: (Only in Production)] <-- // something like this???
[Route("api/[controller]")]
public class TestController : Controller
{
...
答案 0 :(得分:16)
ASP.NET核心授权基于策略。您可能已经看到,AuthorizeAttribute
可以采用策略名称,因此它知道要授权的请求需要满足哪些条件。我建议您阅读有关该主题的great documentation。
回到您的问题,看起来您没有使用特定的政策,因此它使用默认的政策,默认为requires the user to be authenticated。
您可以在Startup.cs
中更改该行为。如果您处于开发模式,则可以重新定义默认策略,以使其不具备任何要求:
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthorization(x =>
{
// _env is of type IHostingEnvironment, which you can inject in
// the ctor of Startup
if (_env.IsDevelopment())
{
x.DefaultPolicy = new AuthorizationPolicyBuilder().Build();
}
});
}
im1dermike在评论中提到AuthorizationPolicy
至少需要一个要求,我们可以看到here。该代码最近没有被引入,所以这意味着上面的解决方案一直都被打破了。
要解决此问题,我们仍然可以利用AuthorizationPolicyBuilder
的{{3}}方法并添加虚拟要求。这看起来像是:
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthorization(x =>
{
// _env is of type IHostingEnvironment, which you can inject in
// the ctor of Startup
if (_env.IsDevelopment())
{
x.DefaultPolicy = new AuthorizationPolicyBuilder()
.RequireAssertion(_ => true)
.Build();
}
});
}
这确保我们在授权策略中至少有一个要求,并且我们知道它将始终通过。
答案 1 :(得分:1)
我最终得到了这个,可能会有所帮助:
public class OnlyDebugModeAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext context)
{
base.OnActionExecuted(context);
}
public override void OnActionExecuting(ActionExecutingContext context)
{
#if DEBUG
//Ok
#else
context.Result = new ForbidResult();
return;
#endif
}
}
然后将其应用于控制器
[OnlyDebugMode]
[Route("api/[controller]")]
[ApiController]
public class DebugController : ControllerBase
{
答案 2 :(得分:0)
这是我的解决方法:
控制器的新属性:
[AzureADAuthorize]
AzureADAuthorize.cs:
public class AzureADAuthorize : AuthorizeAttribute
{
public AzureADAuthorize() : base(AzureADPolicies.Name)
{
}
}
AzureADPolicies.cs:
public static class AzureADPolicies
{
public static string Name => "AzureADAuthorizationRequired";
public static void Build(AuthorizationPolicyBuilder builder)
{
if (StaticRepo.Configuration.GetValue<bool>("EnableAuthorization") == true)
{
var section = StaticRepo.Configuration.GetSection($"AzureAd:AuthorizedAdGroups");
var groups = section.Get<string[]>();
builder.RequireClaim("groups", groups);
}
else if (StaticRepo.Configuration.GetValue<bool>("EnableAuthentication") == true)
{
builder.RequireAuthenticatedUser();
}else
{
builder
.RequireAssertion(_ => true)
.Build();
}
}
}
Startup.cs:
//Authentication & Authorization
#region AUTHENTICATION / AUTHORICATION
StaticRepo.Configuration = Configuration;
services.AddAuthorization(options =>
{
options.AddPolicy(
AzureADPolicies.Name, AzureADPolicies.Build);
});
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind("AzureAd", options));
#endregion
Appsettings.json:
"EnableAuditLogging": false,
"EnableAuthentication": true,
"EnableAuthorization": false,
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"Domain": "https://MyDomain.onmicrosoft.com/",
"TenantId": "b6909603-e5a8-497d-8fdb-7f10240fdd10",
"ClientId": "6d09a1bf-4678-4aee-b67c-2d6df68d5324",
"CallbackPath": "/signin-oidc",
//Your Azure AD Security Group Object IDs that users needs to be member of to gain access
"AuthorizedAdGroups": [
"568bd325-283f-4909-9fcc-a493d19f98e8",
"eee6d366-0f4d-4fca-9965-b2bc0770506d"
]
}
(这些是随机的向导)
现在,您可以有条件地控制是否要进行匿名访问,Azure广告身份验证,身份验证+组授权。您还需要在Azure广告应用程序清单文件中设置一些内容才能使其正常工作,但我认为这不在此处范围内。