0

I want to use OAuth for login

And can use cookies and Bearer Authorization for Authentication

Reference from ASP.NET Core 2.0 combining Cookies and Bearer Authorization for the same endpoint

but cookie can function normally, Bearer Authorization can't

Here is the setup I have for Authentication in my Startup.cs:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();

        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        // JWT tokens
        .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options => // JwtBearerDefaults.AuthenticationScheme
        {
            options.Authority = Configuration["auth:oidc:AuthBaseUri"];
            options.Audience = Configuration["auth:oidc:Scopes"];

            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidateLifetime = true,
                ValidateIssuerSigningKey = true,
                NameClaimType = "name",
                RoleClaimType = "role",
            };

            options.SaveToken = true;
        });

        services.AddAuthentication(options =>
        {
            options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
        })
        .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
        .AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
        {
            options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            options.AuthenticationMethod = OpenIdConnectRedirectBehavior.RedirectGet;

            options.Authority = Configuration["auth:oidc:AuthBaseUri"];
            options.ClientId = Configuration["auth:oidc:ClientId"];
            options.ClientSecret = Configuration["auth:oidc:ClientSecret"];

            options.Scope.Clear();
            options.Scope.Add("openid roles profile");
            options.Scope.Add(Configuration["auth:oidc:Scopes"]);

            options.GetClaimsFromUserInfoEndpoint = true;
            options.ClaimActions.MapJsonKey("role", "role", "role");

            options.UseTokenLifetime = true;

            options.TokenValidationParameters = new TokenValidationParameters
            {
                NameClaimType = "name",
                RoleClaimType = "role"
            };

            options.SaveTokens = true;
            options.ResponseType = OpenIdConnectResponseType.Code;
        });

        services.AddAuthorization(options =>
        {
            var defaultAuthorizationPolicyBuilder = new AuthorizationPolicyBuilder(CookieAuthenticationDefaults.AuthenticationScheme, JwtBearerDefaults.AuthenticationScheme);
            defaultAuthorizationPolicyBuilder = defaultAuthorizationPolicyBuilder.RequireAuthenticatedUser();

            options.DefaultPolicy = defaultAuthorizationPolicyBuilder.Build();
        });
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseHttpsRedirection();

        app.UseRouting();

        app.UseAuthentication(); 
        app.Use(async (context, next) =>
        {
            await next();
            var bearerAuth = context.Request.Headers["Authorization"]
                .FirstOrDefault()?.StartsWith("Bearer ") ?? false;
            if (context.Response.StatusCode == 401
                && !context.User.Identity.IsAuthenticated
                && !bearerAuth)
            {
                await context.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme);
            }
        });
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }

I have the following sample endpoint:

    [HttpGet]
    [Authorize(Roles = "xxxRole")]
    public IEnumerable<WeatherForecast> Get()
    {
        var rng = new Random();
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateTime.Now.AddDays(index),
            TemperatureC = rng.Next(-20, 55),
            Summary = Summaries[rng.Next(Summaries.Length)]
        })
        .ToArray();
    }

jwt sample:

eyJhbGciOiJSUzI1NiIsImtpZCI6InlYa2hPMTc5XzlUM0Jkc1ZBbjhEV2ciLCJ0eXAiOiJhdCtqd3QifQ.eyJuYmYiOjE2MjEzNDM3NzYsImV4cCI6MTYyMTM0NzM3NiwiaXNzIjoiaHR0cHM6Ly9taWNyb3N1Z2Fyb2F1dGguYXp1cmV3ZWJzaXRlcy5uZXQiLCJhdWQiOiJ0QXV0aG9yaXphdGlvbkNvZGVBcGkiLCJjbGllbnRfaWQiOiJ0QXV0aG9yaXphdGlvbkNvZGVDbGllbnRJZCIsInN1YiI6IjUxMzI1ODExLWU2Y2EtNGRkNS05NmMzLTk4YzY1OTYxNzQxNyIsImF1dGhfdGltZSI6MTYyMTMzNjc2NywiaWRwIjoibG9jYWwiLCJ3ZWJzaXRlIjpbImh0dHBzOi8vbG9jYWxob3N0OjQ0Mzg4IiwiaHR0cHM6Ly9sb2NhbGhvc3Q6NTAwMSJdLCJyb2xlIjoidFJvbGUiLCJqdGkiOiJzUUtvY3ZwbWdfcjY1cERtc1VXTXNnIiwic2NvcGUiOlsib3BlbmlkIiwicHJvZmlsZSIsInRBdXRob3JpemF0aW9uQ29kZUFwaSJdLCJhbXIiOlsicHdkIl19.FiZJDMOXYA72yd-q7qesU1apqxURDKE73IfGGuyHmDVKlc8UWpkTIeEl4bUBpoahs2FSNs5FX7fdgS1uq3xhAH9D-7Mozg8R0C1fhmAkCU8JvQ9TRoKUf8IjdZTO0dv59mBryAisUBUfygiAOUbnvcsHODGX5MV7EmViw8rcgbusSmI7SC6wSeFBaD9IbiJVsBfdveD2NVMTpJacTZfDb15ngo5HS3K571pZ9mFMgMVqu9-SzOb6PdwZXcHuPXUXzFQfJCYBOpWMA_kVHtI5jhUEm1GeG7S92fgk7eHYHj7cBiPIqeHTvlf5ab6AQ3kooNgEzFgSQLU0M66z8HlocQ
  • If only using one of the authentication methods, such as Cookie authentication or JWT Bearer Authentication, whether the application works well or not? – Zhi Lv May 19 '21 at 07:18
  • Since you are using multiple Authentication Scheme, if you are using `[Authorize(Roles = "xxxRole")]`, both the cookie and bearer auth will work. And it need the current user's Identity contains the cookie and bearer, if not it will return the 401 error. So, when you use the Authorize attribute, you should set the Authentication Scheme. Refer [this article](https://learn.microsoft.com/en-us/aspnet/core/security/authorization/limitingidentitybyscheme). Besides, check this [known issue](https://github.com/dotnet/aspnetcore/issues/26002) when using multiple authentication schemes. – Zhi Lv May 19 '21 at 07:18
  • If only using one of the authentication methods, such as Cookie authentication or JWT Bearer Authentication, whether the application works well or not? => Yes – microsugar May 20 '21 at 08:35

0 Answers0