Search code examples
c#asp.net-coreidentityserver4

IdentityServer4 Authorization returns 403 forbidden instead of 401


I am using isentittyserver4 and I authorized my controller or actions.

[Authorize(Roles ="app.admin")]
[Route("products")]
public class ProductsController : Controller
{
}

My token contains roles. I can access roles in User object property.

  • User.IsInRole("app.admin"); //false
  • User.IsInRole("app.viewer"); //true

But if I send request with token that does not contain app.admin but contains app.viewer

But request response is 403 forbidden. But it shold be 401 unauthorized.

public class Startup
{
        public void ConfigureServices(IServiceCollection services)
        {
           services.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
                .AddIdentityServerAuthentication(options =>
                {
                    options.Authority = Configuration.GetValue<string>("Authority");
                    options.ApiName = Configuration.GetValue<string>("ApiName");
                    options.RequireHttpsMetadata = false;
                });

            services.AddMvc();            
        }
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseAuthentication();
            app.UseMvc();
        }
}

Solution

  • It should be 403, or at least anything other than 401.

    Here is why.

    Suppose the pipeline returns 401. The handler will treat the request as unauthenticated and will trigger the SSO flow. However, the user is already authenticated at the Identity Provider side. The Identity Provider will then return the same/new token silently and the flow will return to the application. Depending on the actual return addres, one of two scenarios happens:

    • the return address is always the main page of your app - the user will notice they are redirected to the main page but they believe they are already authenticated and this should not happen. You will get reports of a possible bug in your app.

    • the return address is the very same address that triggered the SSO flow. But we already discussed if this returns 401, it goes back to the Identity Provider. The browser falls then in an endless loop of redirects between the IdP and your app. You will get reports of a critical bug.

    If instead the authorization returns 403 rather than 401, you can catch it at the end of the pipeline at your app side (I believe a simple action filter should do the job assuming you check the status in the OnActionExecuted) and handle in an appropriate way, e.g. return an information of what's the reason the requested resource cannot be displayed because the users lacks required permissions.