2

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();
        }
}
Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
barteloma
  • 6,403
  • 14
  • 79
  • 173
  • 2
    No, the codes are correct only. If a request does not contain the token or invalid token then it is Unauthorized, but in your case the token is valid only the claim validation fails, so it is perfectly correct to say that the server identified the user and is valid, but does not have the required claim to access this particular resource. – Thangadurai Mar 29 '18 at 09:18
  • But role is not valid for this request. So it should be unauthorized. – barteloma Mar 29 '18 at 09:24
  • 5
    Authentication is different from Authorization. In your case it is the authorization that fails, though he is an authenticated user. – Thangadurai Mar 29 '18 at 09:30
  • 5
    Just think of it as 401 = I don't know who you are and 403 = I know who you are but you cannot do that. – Kirk Larkin Mar 29 '18 at 09:42

1 Answers1

5

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.

Wiktor Zychla
  • 47,367
  • 6
  • 74
  • 106