问题
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.
回答1:
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
};
return context.Response.WriteAsync(payload.ToString());
};
});
回答2:
Was facing same issue, tried the solution provided by Pinpoint but it didnt work for me on ASP.NET core 2.0. But based on Pinpoint's solution and some trial and error, the following code works for me.
var builder = services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(o =>
{
o.Authority = "http://192.168.0.110/auth/realms/demo";
o.Audience = "demo-app";
o.RequireHttpsMetadata = false;
o.Events = new JwtBearerEvents()
{
OnAuthenticationFailed = c =>
{
c.NoResult();
c.Response.StatusCode = 500;
c.Response.ContentType = "text/plain";
c.Response.WriteAsync(c.Exception.ToString()).Wait();
return Task.CompletedTask;
},
OnChallenge = c =>
{
c.HandleResponse();
return Task.CompletedTask;
}
};
});
来源:https://stackoverflow.com/questions/48649717/addjwtbearer-onauthenticationfailed-return-custom-error