User.Identity.IsAuthenticated Being Checked Twice?

390 Views Asked by At

I'm a bit new to .net core and I'm struggling with how to approach this, so forgive me if my current approach is wrong or inherently frowned upon.

However, I have set up my application to use Jwt and [Authorization] when working with any API Endpoints. Since this is not a single page application, I need to authorize access to specific views within the application as well. For example, I only want users to be given access to the Dashboard of the application if they have been signed in.

My sign in method (from a pseudo description) checks credentials and generates a JWT token to return to the client side for storage if everything checks out. Before returning the token to the client I am also calling the following:

await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, User);

Which works for the most part. It creates a cookie and stores information in the cookie, but when it gets to the controller where I want to validate if the user is authenticated, the validation runs twice. The first time it runs, the isAuthenticated is false. The second time it runs, it is true. I'm having trouble finding out why it's running twice (maybe I've missed something here?), and beginning to wonder if I'm approaching this correctly or not.

public IActionResult Dashboard()
{
    bool isAuthenticated = User.Identity.IsAuthenticated;

    return isAuthenticated ? View() : (IActionResult)Forbid();
}

My Jwt Authorization works just fine, but my authorization on cookies is not working at all. For example, the Authorize in the below method is working flawlessly.

[Authorize]
public OkObjectResult Test()
{
    return Ok(HttpStatusCode.OK);
}

Here is my Startup.cs ConfigureServices

    public void ConfigureServices(IServiceCollection services)
    {

        services.AddAuthorization(auth =>
        {
            auth.AddPolicy("Bearer", new AuthorizationPolicyBuilder()
                .AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme‌​)
                .RequireAuthenticatedUser().Build());
        });

        services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        })
        .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options => 
        {

            options.LoginPath = "/Home/Index";
            options.AccessDeniedPath = "/Home/Index";
            options.Cookie.Name = CookieAuthenticationDefaults.AuthenticationScheme;
            options.ExpireTimeSpan = new TimeSpan(365, 0, 0, 0);
            options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
            options.Cookie.SameSite = SameSiteMode.None;

        })
        .AddJwtBearer(options =>
        {
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateAudience = false,
                //ValidAudience = "the audience you want to validate",
                ValidateIssuer = false,
                //ValidIssuer = "the issuer you want to validate",

                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("XXX")),

                ValidateLifetime = true, //validate the expiration and not before values in the token

                ClockSkew = TimeSpan.FromMinutes(5) //5 minute tolerance for the expiration date
            };
        });

        services.Configure<CookiePolicyOptions>(options =>
        {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.CheckConsentNeeded = context => true;
            options.Secure = CookieSecurePolicy.SameAsRequest;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });

        services.AddMvc(options => 
        {
            options.Filters.Add(new RequireHttpsAttribute());
        })
        .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

        // Configure the DB Access.
        services.AddDbContext<DbAccess>(options => 
                    options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

        // Ensure that we are adding the repos to our scope.
        services.AddScoped<IResetRepository, ResetRepository>();
        services.AddScoped<IAuthRepository, AuthRepository>();

        // Inject our email settings.
        services.Configure<EmailSettings>(Configuration.GetSection("EmailSettings"));

        // Let's set up the email sender as transient.
        services.AddTransient<IEmailSender, EmailSender>();
    }

And here is my Configure method within Startup.cs

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            app.UseHsts();
        }

        var cookiePolicyOptions = new CookiePolicyOptions
        {
            Secure = CookieSecurePolicy.SameAsRequest,
            MinimumSameSitePolicy = SameSiteMode.None
        };

        app.UseCookiePolicy(cookiePolicyOptions);

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseCookiePolicy();
        app.UseAuthentication();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }

I'm hoping I've not missed anything super obvious here. Any assistance is greatly appreciated.

Here are some images (added after the initial post). Hopefully these can help resolve the problem? First pass where IsAuthenticated is false

Second pass where IsAuthenticated is true and there are claims present.

0

There are 0 best solutions below