I would like to use my Open Data (OData) Controllers to access data from a third party grid tool in MVC (using cookie authentication), and I would also like to use the same controllers to synchronize data with a mobile Xamarin app (using token authentication).
Here is an extract from my startup file...
services.AddAuthentication(options =>
{
//options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
//options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
//options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie(options => options.SlidingExpiration = true)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false,
ValidateAudience = false,
ValidateLifetime = false,
RequireExpirationTime = false,
ValidIssuer = authOptions.Issuer,
ValidAudience = authOptions.Audience,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(authOptions.SecureKey))
};
});
and the relevant bits of the controllers look like the following...
[Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme), Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public class FooODataController : ODataController {...}
The problem is that both cookies and bearer tokens are always challenged, so that the user is never authenticated. Does anyone know a way of implementing this so that the user is authenticated if either of the challenges are successful?
It's because there is two [Authorize(..), Authorize(..)] attributes, instead you should have one with multiple schemas: (see this)
[Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme + "," + JwtBearerDefaults.AuthenticationScheme)]
public class FooODataController : ODataController