I am using OpenIddict for JWT authentication in my ASP.NET Core 2.0 app.
I have a method with [AllowAnonymous]
attribute. User is Authenticated on client (access token is sent), but access token is invalid (for some reason which is not important right now) so
contextAccessor?.HttpContext?.User?.FindFirst(ClaimTypes.NameIdentifier)
returns null
.
Problem is that I return a different set of data if user is authenticated or anonymous. Server thinks user is anonymous, and client thinks user is logged in.
I would like to return http error code (not 200) if request has Authorization: Bearer eyJhb....
request header, but on server User is null. How?
This already works if method has Authorize
attribute (it returns 403), but not on AllowAnonymous
Controller method.
I think I need something like AutomaticAuthenticate
that exist in ASP.NET Core 1. I would like to return 401 if Context.Token
is set, but user does not exist.
This is my setup:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(o =>
{
o.Authority = this.Configuration["Authentication:OpenIddict:Authority"];
o.Audience = "Web"; //Also in Auhorization.cs controller.
o.RequireHttpsMetadata = !this.Environment.IsDevelopment();
if (this.Environment.IsDevelopment())
{
//This ensures that access token is valid, if application is restarted. See also AddOpenIddict in this file.
o.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("ThisIsSecretKeyOnlyInDevelopmentSoItIsSafe")),
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
RequireExpirationTime = true
};
}
o.Events = new JwtBearerEvents()
{
OnMessageReceived = context =>
{
if (context.Request.Path.ToString().StartsWith("/HUB/"))
context.Token = context.Request.Query["access_token"];
else
{
if (context.Request.Query.ContainsKey("access_token")) //We can download file with acces_token in url
context.Token = context.Request.Query["access_token"];
}
return Task.CompletedTask;
},
//It would be nice to report error to user with custom status code, but this is not possible: https://stackoverflow.com/questions/48649717/addjwtbearer-onauthenticationfailed-return-custom-error?noredirect=1#comment84308248_48649717
OnAuthenticationFailed = context =>
{
this._logger.LogInformation(Log.OpPIS, "JWT authentication failed.");
if (this.Environment.IsDevelopment())
Debug.Write(context.Exception.Message);
return Task.CompletedTask;
}
};
});