Using PolicyServer.Local causes the exception but I can't reprodure the exception in a test project.
The page fails to load. It seems to happen wherever the [Authorize] attribute is present. I have a global AuthorizeFilter as well for a default policy of require authenticated user.
Browse to any page with the [Authorize] attribute (Test project works though)
No exception.
Exception is thrown.
[Check this line of core]https://github.com/aspnet/Mvc/blob/330b74f0ab4c8e337ec93a9129fc9f2df7eca135/src/Microsoft.AspNetCore.Mvc.Core/Authorization/AuthorizeFilter.cs#L143
ArgumentNullException: Value cannot be null.
Parameter name: policy
Microsoft.AspNetCore.Authorization.AuthorizationPolicyBuilder.Combine(AuthorizationPolicy policy)
Microsoft.AspNetCore.Authorization.AuthorizationPolicyBuilder..ctor(AuthorizationPolicy policy)
Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter.GetEffectivePolicyAsync(AuthorizationFilterContext context)
Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter.OnAuthorizationAsync(AuthorizationFilterContext context)
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
Does anyone have any idea what might be causing this? I'm using ASP.NET Core 2.1 release candidate.
My package references are as follows:
<PackageReference Include="Microsoft.AspNetCore.HttpsPolicy" Version="2.1.0-rc1-final" />
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="2.1.0-rc1-final" />
<PackageReference Include="Serilog" Version="2.7.1" />
<PackageReference Include="Serilog.Extensions.Logging" Version="2.0.2" />
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
<PackageReference Include="Serilog.Sinks.File" Version="4.0.0" />
<PackageReference Include="StructureMap" Version="4.6.1" />
<PackageReference Include="StructureMap.Microsoft.DependencyInjection" Version="1.4.0" />
My OS is Windows 10 and I'm using IIS Express as web server.
My configured roles and premissions are:
"Policy": {
"roles": [
{
"name": "Admin",
"subjects": [],
"identityRoles": [ "Admin" ]
},
{
"name": "ToolsAdmin",
"subjects": [],
"identityRoles": [ "ToolsAdmin" ]
},
{
"name": "Tester",
"subjects": [],
"identityRoles": [ "Tester" ]
}
],
"permissions": [
{
"name": "ManageUsers",
"roles": [ "Admin" ]
},
{
"name": "ManageRoles",
"roles": [ "Admin" ]
},
{
"name": "ManageTools",
"roles": [ "Admin", "ToolsAdmin" ]
},
{
"name": "ManageMedia",
"roles": [ "Admin" ]
},
{
"name": "ManageReports",
"roles": [ "Tester" ]
},
{
"name": "ViewStartQuestions",
"roles": [ "Admin", "Tester" ]
},
{
"name": "MakeTestChanges",
"roles": [ "Tester" ]
}
]
}
I just logged an issue in AspNet/MVC but it is related to PolicyServer.Local so I would appreciate any input you migh have. cc @leastprivilege @brockallen
Thanks for reporting this issue.
@javiercn, can you please look into this?
@HaoK As he's the expert in this area.
@grantmcdade I can't repro this.
Can you provide a minimal repro project that showcases the issue?
Thanks.
thanks @javiercn. I have already spent the last two days trying to do exactly that but as you found out it's not an easy problem to reproduce. I don't have this setup to debug this and since I'm no expert I don't know what might be causing the problem. I will continue to try and reproduce this in a smaller Project.
How do you get a null effective policy?
Startup.cs is a good place to start
This bug might be the same issue with a repro: https://github.com/aspnet/Security/issues/1764
Ok so the issue appears to be when AuthorizeFilter is created with a null effective policy, Combine does not allow passing in a null policy, GetEffectivePolicy should be checking for null policy and combining with a empty policy rather than passing in null.
Ok so the workaround is to turn off AllowCombiningAuthorizeFilters in mvcOptions
@HaoK Can taking it from here?
Sure
fyi @blowdart @ajcvickers
Thanks for looking into this so quickly. I have created the project to help with reproduction of the issue.
https://github.com/grantmcdade/CTG.Web
It is basically the original project with as much as possible stripped out. If you try to view "Account -> Details" while already logged in then the exception occurs.
@grantmcdade Thanks for the repor.
@HaoK Can you take a look to ensure your fix covers @grantmcdade issue?
Yep its definitely the same issue, so policy server uses a custom IAuthorizationPolicyProvider, so this is going to hit everyone who uses policy server + 2.1 :(
@grantmcdade have you confirmed that the workaround works for you as well? Turning off the combination behavior should avoid hitting this code path.
mvcOptions.AllowCombiningAuthorizeFilters = false
I am using PolicyServer.Local and also hitting this issue after upgrading from ASP.NET Core 2.0 to 2.1 RC.
mvcOptions.AllowCombiningAuthorizeFilters = false works for me. Thanks!
Yes, @HaoK I can confirm that it does work.
Edit: Referring to the workaround of setting
mvcOptions.AllowCombiningAuthorizeFilters = false
Moved this out to 2.2, as the workaround is pretty cheap and this doesn't meet the bar for a patch.
Fixed via https://github.com/aspnet/Mvc/pull/8068
Most helpful comment
@grantmcdade have you confirmed that the workaround works for you as well? Turning off the combination behavior should avoid hitting this code path.
mvcOptions.AllowCombiningAuthorizeFilters = false