Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"There was an error trying to log you in: '' " Blazor WebAssembly using IdentiyServer Authentication

I have a Blazor WebAssembly app using IdentityServer that comes with the template as my authentication service. I am having an issue where some users are seeing "There was an error trying to log you in: ''" once they try to login. I had users clear cookies and cache, and they are still experiencing this problem in all their browsers. The weird thing is that most users are able to login, but only a small percent is getting that error. Another odd thing is that it seems like if they use another device such as a phone, another pc, or ipad it works. What could be causing this issue? I have been having trouble trying to debug this issue as I am not able to replicate it on my end and so far not seeing any logs to get any info.

This app is hosted in Google Cloud Platform using linux Docker container.

Thank you in advance

Edit: Here is my startup class

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
    private const string XForwardedPathBase = "X-Forwarded-PathBase";
    private const string XForwardedProto = "X-Forwarded-Proto";

    // This method gets called by the runtime. Use this method to add services to the container.
    // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors(options =>
        {
            options.AddPolicy(name: MyAllowSpecificOrigins,
                              builder =>
                              {
                                  builder.WithOrigins("https://www.fakedomainexample.com",
                                                      "https://fakedomainexample.com");
                              });
        });

        services.AddHttpContextAccessor();

        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseMySql(
                Configuration.GetConnectionString("ConnectionString")));

        services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
            .AddRoles<IdentityRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>();

        // For some reason, I need to explicitly assign the IssuerUri or else site gets invalid_issuer error
        services.AddIdentityServer(x => x.IssuerUri = "https://www.fakedomainexample.com").AddApiAuthorization<ApplicationUser, ApplicationDbContext>(options => {
            options.IdentityResources["openid"].UserClaims.Add("name");
            options.ApiResources.Single().UserClaims.Add("name");
            options.IdentityResources["openid"].UserClaims.Add("role");
            options.ApiResources.Single().UserClaims.Add("role");
        });
        JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("role");

        services.Configure<IdentityOptions>(options =>
        {
            // Password settings.
            options.Password.RequireDigit = true;
            options.Password.RequireLowercase = true;
            options.Password.RequireNonAlphanumeric = true;
            options.Password.RequireUppercase = true;
            options.Password.RequiredLength = 8;
            options.Password.RequiredUniqueChars = 1;

            // User settings.
            options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            options.User.RequireUniqueEmail = true;
            options.SignIn.RequireConfirmedAccount = false;
        });

        // Added Cookie options below to fix an issue with login redirect in Chrome for http
        // https://stackoverflow.com/questions/60757016/identity-server-4-post-login-redirect-not-working-in-chrome-only
        // This one worked: https://stackoverflow.com/questions/63449387/cannot-redirect-back-to-angular-client-after-login-in-identity-server
        services.ConfigureExternalCookie(option =>
        {
            option.LoginPath = "/Account/Login";
            option.Cookie.IsEssential = true;
            option.Cookie.SameSite = SameSiteMode.Lax;
        });
        services.ConfigureApplicationCookie(option =>
        {
            option.LoginPath = "/Account/Login";
            option.Cookie.IsEssential = true;
            option.Cookie.SameSite = SameSiteMode.Lax;
        });


        services.AddAuthentication()
            .AddIdentityServerJwt();

        services.AddControllersWithViews();
        services.AddRazorPages();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        app.UseForwardedHeaders(new ForwardedHeadersOptions
        {
            ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
        });

        app.UseRewriter(new RewriteOptions()
            .AddRedirectToWwwPermanent());

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseDatabaseErrorPage();
            app.UseWebAssemblyDebugging();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }
        app.Use((context, next) =>
        {
            if (context.Request.Headers.TryGetValue(XForwardedPathBase, out StringValues pathBase))
            {
                context.Request.PathBase = new PathString(pathBase);
            }

            if (context.Request.Headers.TryGetValue(XForwardedProto, out StringValues proto))
            {
                context.Request.Scheme = proto;
            }
        //context.SetIdentityServerOrigin("https://www.fakedomainexample.com"); 
        return next();
        });
        app.UseHttpsRedirection();
        app.UseBlazorFrameworkFiles();
        
        const string cacheMaxAge = "3600";
        app.UseStaticFiles(new StaticFileOptions
        {
            OnPrepareResponse = ctx =>
            {
                ctx.Context.Response.Headers.Add("Cache-Control", $"public, max-age={cacheMaxAge}");
            }
        });
        app.UseCookiePolicy(new CookiePolicyOptions
        {
            MinimumSameSitePolicy = Microsoft.AspNetCore.Http.SameSiteMode.Lax,
        });

        app.UseRouting();
        app.UseCors(MyAllowSpecificOrigins);

        app.UseIdentityServer();
        app.UseAuthentication();
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapRazorPages();
            endpoints.MapControllers();
            endpoints.MapFallbackToFile("index.html");
        });
    }
}
like image 346
Jabo Avatar asked Nov 09 '20 21:11

Jabo


People also ask

How do I add authentication to Blazor?

There is an option available to enable authentication for the Blazor app when you create the application. To enable authentication for Blazor server app, click on “Change” under “Authentication section and select “Individual User Accounts” option and then click on “Ok” button when you create a new Blazor server app.

How do you handle errors in Blazor?

When an error occurs, Blazor apps display a light yellow bar at the bottom of the screen: During development, the bar directs you to the browser console, where you can see the exception. In production, the bar notifies the user that an error has occurred and recommends refreshing the browser.

Is authenticated Blazor?

Blazor Server authentication Blazor Server apps operate over a real-time connection that's created using SignalR. Authentication in SignalR-based apps is handled when the connection is established. Authentication can be based on a cookie or some other bearer token.

Does Blazor work in Chrome?

Your Blazor WASM application will run fine on Chrome, Edge, Firefox, Safari and also on the mobile variants of these.

How does Blazor authenticate the user?

Blazor uses the existing ASP.NET Core authentication mechanisms to establish the user's identity. The exact mechanism depends on how the Blazor app is hosted, Blazor WebAssembly or Blazor Server. In Blazor WebAssembly apps, authentication checks can be bypassed because all client-side code can be modified by users.

What is Blazor WebAssembly security?

Blazor WebAssembly Security Overview Blazor WebAssembly is a single page application (SPA) and, we can integrate different authorization options inside it. The most common option is using the tokens with OAuth2 and OIDC. As the most common option, we are going to use it in this series as well.

What is identityserver in Blazor WebAssembly?

So basically, after we log in with our Blazor WebAssembly application, the IdentityServer will provide us with id and access tokens. We are going to use the id token for the user’s information and the access token to access our Web API’s protected resources.

What is ASP NET Core in Blazor?

ASP.NET Core supports the configuration and management of security in Blazor apps. Security scenarios differ between Blazor Server and Blazor WebAssembly apps. Because Blazor Server apps run on the server, authorization checks are able to determine: The UI options presented to a user (for example, which menu entries are available to a user).


2 Answers

We also faced this problem. The error appears if the server time does not match the client time. Experiments have shown that it is enough to have a difference of 10 minutes. Ideally, the time on the client and server should be in sync. We are currently asking customers to check the time on the device, but this is not a solution to the problem.

like image 83
rayder2007 Avatar answered Oct 25 '22 07:10

rayder2007


Who have this problem when publishing on IIS with a self-signed certificate, it may be caused by auth of Application Pool on read the Certificate.

For solve this problem, open certification manager, right click on the certificate, all tasks, private key manager and insert IIS group (IIS_IUSRS) for read/write permission. For test, try "Everyone".

like image 1
Nathan Gallete Avatar answered Oct 25 '22 07:10

Nathan Gallete