asp.net-coreauthenticationodatasyncfusiondata-synchronization

Is there a way of using two authentication schemes for the same controller?


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?


Solution

  • 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