Search code examples
c#authorizationasp.net-core-2.0user-roles

asp.net core 2.0 app crashes when role based authorization faild


I want to authorize user based on roles:

[Authorize(Roles = "Administrator")]
public class TestController : Controller
{    
    public IActionResult Index()
    {
        return Ok();
    }
}

When the user has Claim(type: "Role", value: "Administrator"), it works ok. When he doesn't the application crashes. When debugging in VS, it just stops and IIS Express process ends. I don't see any exception. I only see this output debug output:

Application Insights Telemetry: {"name":"Microsoft.ApplicationInsights.Dev.2822d75fd5c24f0180cd7a0cd61c0e40.Message","time":"2017-12-06T12:03:16.7897859Z","iKey":"2822d75f-d5c2-4f01-80cd-7a0cd61c0e40","tags":{"ai.internal.sdkVersion":"aspnet5c:2.1.1","ai.location.ip":"127.0.0.1","ai.internal.nodeName":"MY-DESKTOP","ai.cloud.roleInstance":"MY-DESKTOP","ai.operation.parentId":"|a2488207-417e03727b6f68b7.","ai.operation.name":"GET test/Index","ai.operation.id":"a2488207-417e03727b6f68b7","ai.application.ver":"1.0.0.0"},"data":{"baseType":"MessageData","baseData":{"ver":2,
    "message":"Authorization failed for user: liero@mycompany.com.","severityLevel":"Information","properties":{"CategoryName":"Microsoft.AspNetCore.Authorization.DefaultAuthorizationService","AspNetCoreEnvironment":"Development","{OriginalFormat}":"Authorization failed for user: {UserName}.","DeveloperMode":"true","UserName":"liero@mycompany.com"}}}}

Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.

Application Insights Telemetry: {"name":"Microsoft.ApplicationInsights.Dev.2822d75fd5c24f0180cd7a0cd61c0e40.Message","time":"2017-12-06T12:03:16.7962379Z","iKey":"2822d75f-d5c2-4f01-80cd-7a0cd61c0e40","tags":{"ai.internal.sdkVersion":"aspnet5c:2.1.1","ai.location.ip":"127.0.0.1","ai.internal.nodeName":"MY-DESKTOP","ai.cloud.roleInstance":"MY-DESKTOP","ai.operation.parentId":"|a2488207-417e03727b6f68b7.","ai.operation.name":"GET test/Index","ai.operation.id":"a2488207-417e03727b6f68b7","ai.application.ver":"1.0.0.0"},"data":{"baseType":"MessageData","baseData":{"ver":2,
    "message":"Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.","severityLevel":"Information","properties":{"CategoryName":"Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker","AspNetCoreEnvironment":"Development","{OriginalFormat}":"Authorization failed for the request at filter '{AuthorizationFilter}'.","DeveloperMode":"true","AuthorizationFilter":"Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter"}}}}

Microsoft.AspNetCore.Mvc.ForbidResult:Information: Executing ForbidResult with authentication schemes ().

Application Insights Telemetry: {"name":"Microsoft.ApplicationInsights.Dev.2822d75fd5c24f0180cd7a0cd61c0e40.Message","time":"2017-12-06T12:03:16.8222130Z","iKey":"2822d75f-d5c2-4f01-80cd-7a0cd61c0e40","tags":{"ai.internal.sdkVersion":"aspnet5c:2.1.1","ai.location.ip":"127.0.0.1","ai.internal.nodeName":"MY-DESKTOP","ai.cloud.roleInstance":"MY-DESKTOP","ai.operation.parentId":"|a2488207-417e03727b6f68b7.","ai.operation.name":"GET test/Index","ai.operation.id":"a2488207-417e03727b6f68b7","ai.application.ver":"1.0.0.0"},"data":{"baseType":"MessageData","baseData":{"ver":2,
    "message":"Executing ForbidResult with authentication schemes ().","severityLevel":"Information","properties":{"CategoryName":"Microsoft.AspNetCore.Mvc.ForbidResult","AspNetCoreEnvironment":"Development","{OriginalFormat}":"Executing ForbidResult with authentication schemes ({Schemes}).","DeveloperMode":"true","Schemes":"System.String[]"}}}}

EDIT: I've noticed that this happens when using AddOpenIdConnect authentication builder. When I comment it out, it redirects me to some default "forbidden" url

services.AddAuthentication(sharedOptions =>
{
    sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
  .AddCookie(option => option.Cookie.SameSite = SameSiteMode.None)
  .AddOpenIdConnect(option =>
  {
      option.ClientId = config.ClientId;
      option.Authority = String.Format(config.AadInstance, config.Tenant);
      option.SignedOutRedirectUri = config.PostLogoutRedirectUri;
      option.Events = new OpenIdConnectEvents
      {
          OnRedirectToIdentityProvider = redirectContext =>
          {
              bool isAjaxRequest = redirectContext.HttpContext.Request.Headers["x-requested-with"] == "XMLHttpRequest";
              if (isAjaxRequest)
              {
                  redirectContext.HttpContext.Response.StatusCode = StatusCodes.Status401Unauthorized;
                  redirectContext.HttpContext.Response.Headers["Location"] = "/Account/Login";
                  redirectContext.HandleResponse();
              }
              return Task.CompletedTask;
          }
      };
  });

Solution

  • from github: Core CLR crashes when using Authorize attribute and OpenIdConnect

    This was patched in 2.0.1 by #1435 https://www.nuget.org/packages/Microsoft.AspNetCore.Authentication.OpenIdConnect/

    The workaround is to set sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;

    I've verified the workaround and it works