I am using Openidict.
I am trying to return custom message with custom status code, but I am unable to do it. My configuration in startup.cs
:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(o =>
{
o.Authority = this.Configuration["Authentication:OpenIddict:Authority"];
o.Audience = "MyApp"; //Also in Auhorization.cs controller.
o.RequireHttpsMetadata = !this.Environment.IsDevelopment();
o.Events = new JwtBearerEvents()
{
OnAuthenticationFailed = context =>
{
context.Response.StatusCode = HttpStatusCodes.AuthenticationFailed;
context.Response.ContentType = "application/json";
var err = this.Environment.IsDevelopment() ? context.Exception.ToString() : "An error occurred processing your authentication.";
var result = JsonConvert.SerializeObject(new {err});
return context.Response.WriteAsync(result);
}
};
});
But the problem is no content is returned. Chrome developer tools report
(failed)
for Status and
Failed to load response data
for response.
I also tried:
context.Response.WriteAsync(result).Wait();
return Task.CompletedTask;
but the result is the same.
Desired behaviour:
I would like to return custom status code with message what went wrong.
It's important to note that both the aspnet-contrib OAuth2 validation and the MSFT JWT handler automatically return a WWW-Authenticate
response header containing an error code/description when a 401 response is returned:
If you think the standard behavior is not convenient enough, you can use the events model to manually handle the challenge. E.g:
services.AddAuthentication()
.AddJwtBearer(options =>
{
options.Authority = "http://localhost:54540/";
options.Audience = "resource_server";
options.RequireHttpsMetadata = false;
options.Events = new JwtBearerEvents();
options.Events.OnChallenge = context =>
{
// Skip the default logic.
context.HandleResponse();
var payload = new JObject
{
["error"] = context.Error,
["error_description"] = context.ErrorDescription,
["error_uri"] = context.ErrorUri
};
context.Response.ContentType = "application/json";
context.Response.StatusCode = 401;
return context.Response.WriteAsync(payload.ToString());
};
});