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

后端 未结 5 477
梦如初夏
梦如初夏 2021-01-30 13:46

I\'ve created a new ASP.NET Core Web Application project in VS17 using the \"Web Application (Model-View-Controller)\" template and \".Net Framework\" + \"ASP.NET Core 2\" as th

5条回答
  •  天涯浪人
    2021-01-30 14:15

    After many hours of research and head-scratching, this is what worked for me in ASP.NET Core 2.2:

    • Use .AddCookie() and .AddJwtBearer() to configure the schemes
    • Use a custom policy scheme to forward to the correct Authentication Scheme.

    You do not need to specify the scheme on each controller action and will work for both. [Authorize] is enough.

    services.AddAuthentication( config =>
    {
        config.DefaultScheme = "smart";
    } )
    .AddPolicyScheme( "smart", "Bearer or Jwt", options =>
    {
        options.ForwardDefaultSelector = context =>
        {
            var bearerAuth = context.Request.Headers["Authorization"].FirstOrDefault()?.StartsWith( "Bearer " ) ?? false;
            // You could also check for the actual path here if that's your requirement:
            // eg: if (context.HttpContext.Request.Path.StartsWithSegments("/api", StringComparison.InvariantCulture))
            if ( bearerAuth )
                return JwtBearerDefaults.AuthenticationScheme;
            else
                return CookieAuthenticationDefaults.AuthenticationScheme;
        };
    } )
    .AddCookie( CookieAuthenticationDefaults.AuthenticationScheme, options =>
    {
        options.LoginPath = new PathString( "/Account/Login" );
        options.AccessDeniedPath = new PathString( "/Account/Login" );
        options.LogoutPath = new PathString( "/Account/Logout" );
        options.Cookie.Name = "CustomerPortal.Identity";
        options.SlidingExpiration = true;
        options.ExpireTimeSpan = TimeSpan.FromDays( 1 ); //Account.Login overrides this default value
    } )
    .AddJwtBearer( JwtBearerDefaults.AuthenticationScheme, options =>
    {
        options.RequireHttpsMetadata = false;
        options.SaveToken = true;
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey( key ),
            ValidateIssuer = false,
            ValidateAudience = false
        };
    } );
    
    services.AddAuthorization( options =>
    {
        options.DefaultPolicy = new AuthorizationPolicyBuilder( CookieAuthenticationDefaults.AuthenticationScheme, JwtBearerDefaults.AuthenticationScheme )
            .RequireAuthenticatedUser()
            .Build();
    } );
    

提交回复
热议问题