I'm trying to set up an ASP.Net 5
web project with JWTBearer authentication
for API Controllers (Controllers decorated with the APIController attribute) and CookieAuthentication
for MVC Controllers (Controller classes derived from Controller, to render Views). The relevant part of my ConfigureServices
method in the Startup
Class looks like this:
services
.AddAuthentication(options =>
{
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
options.SaveToken = true;
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("My Secret Key")),
ValidateAudience = false,
ValidateIssuer = false,
RequireExpirationTime = false,
ValidateLifetime = true
};
})
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
options.LoginPath = "/account/login";
options.LogoutPath = "/account/logout";
options.AccessDeniedPath = "/account/accessdenied";
options.Cookie = new CookieBuilder {SameSite = SameSiteMode.Strict};
options.ExpireTimeSpan = TimeSpan.FromMinutes(20);
});
var schemePolicy = new AuthorizationPolicyBuilder(
CookieAuthenticationDefaults.AuthenticationScheme,
JwtBearerDefaults.AuthenticationScheme)
.RequireAuthenticatedUser()
.Build();
services.AddAuthorization(o => o.DefaultPolicy = schemePolicy);
In an MCV Controller I have an Action
like the below:
[Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)]
public IActionResult AnActionForAuthenticatedUsers()
{
// do some stuff...
return View();
}
Now I would expect that when an unauthenticated request for this action comes in the request will be forwarded to /account/login but it is not. Instead a 401 statuscode
is returned.
The webserver says:
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
Authorization failed. These requirements were not met:
DenyAnonymousAuthorizationRequirement: Requires an authenticated user.
info: Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationHandler[12]
AuthenticationScheme: Cookies was challenged.
info: Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler[12]
AuthenticationScheme: Bearer was challenged.
What am I missing here?
The problem here is not in Authentication policy, but in Authorization configuration Create a separate policy for each type of Authorization and that would work as you are expecting:
services.AddAuthorization(o =>
{
o.AddPolicy(CookieAuthenticationDefaults.AuthenticationScheme, schemePolicy);
o.AddPolicy(JwtBearerDefaults.AuthenticationScheme, schemePolicy);
});