Browser stalls when redirecting from Google Auth back to my application ... But only sometimes

Viewed 199

On Google's Cloud Platform I created an OAuth 2.0 Client ID under Api & Services / Credentials.

I defined it as a Web Application and added Authorized JavaScript origins and Authorized redirect URIs. The two urls added are something like https://localhost: ....

I copied the Client Id and Client Secret to my application ...

Because I am testing on OAuth consent screen I set the Publishing Status as testing and added to test users.

PROBLEM

When testing the application, using a test user, sometimes I am able to login.

At other times the browser stalls, after I enter my credentials, when getting back to my application. It is strange because this happens only sometimes ...

I get this problem with many than one browser like Chrome or Safari.

The browser seems to stall on the following URL:

https://accounts.google.pt/accounts/SetSID

After 60 seconds I get a timeout error on my application's callback url.

UPDATE

I'm starting the login process from the Angular Client application using oidc-client-js:

const settings: UserManagerSettings = {
  automaticSilentRenew: true,
  authority: 'https://localhost:5000',
  client_id: 'spa',
  client_secret: 'secret',
  filterProtocolClaims: true,
  loadUserInfo: true,
  post_logout_redirect_uri: `https://localhost:5002/signout`,
  redirect_uri: `https://localhost:5002/signin`,
  response_mode: 'query',
  response_type: 'code',
  scope: 'openid profile email offline_access api',
  silent_redirect_uri: `https://localhost:5002/renew`
};

let manager = new UserManager(settings);

manager.signinRedirect();

This redirects to the Asp.Net Core with OpenIdDict Auth application.

Then I opt to login with Google which calls the following method and redirects to Google:

public IActionResult Challenge(String provider, String returnUrl = null) {

  String redirectUrl = Url.Action("Callback", "User", new { ReturnUrl = returnUrl });

  AuthenticationProperties properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);

  return new ChallengeResult(provider, properties);

}

The configuration of the Auth application is the following:

public void ConfigureServices(IServiceCollection services) {

  services
    .AddControllersWithViews()
    .SetCompatibilityVersion(CompatibilityVersion.Latest)
    .AddJsonOptions()
    .AddFluentValidation();

  services.AddRouting(x => { x.AppendTrailingSlash = false; x.LowercaseUrls = true; });

  services.AddCors(x => {
    x.AddPolicy("Cors", y => 
      y.WithOrigins("https://localhost:5001", "https://localhost:5002").AllowAnyMethod().AllowAnyHeader().AllowCredentials());
    });

  services.AddDbContext<Context>(x => {

    x.UseSqlServer(Configuration.Get<Options>().Database.Connection, y => {
      y.MigrationsHistoryTable("__Migrations");
      y.UseNetTopologySuite();  
    }).EnableSensitiveDataLogging(Environment.IsDevelopment())
      .UseQueryTrackingBehavior(QueryTrackingBehavior.TrackAll);

    x.UseOpenIddict<Data.Entities.Application, Authorization, Scope, Token, Int32>();

  });

  services
    .AddIdentityCoreWithAuthentication<User>(x => x.AddDefaultOptions())
    .AddEntityFrameworkStores<Context>()
    .AddDefaultTokenProviders()
    .AddUserConfirmation<UserConfirmation<User>>();

  services.ConfigureApplicationCookie(x => {
    x.AccessDeniedPath = "/denied";
    x.Cookie.HttpOnly = false;
    x.Cookie.Name = "auth";
    x.ExpireTimeSpan = TimeSpan.FromMinutes(40);
    x.LoginPath = "/login";
    x.LogoutPath = "/logout";
    x.SlidingExpiration = true;
  });

  services.AddOpenIddict()
  
    .AddCore(x => {

      x.UseEntityFrameworkCore()
       .UseDbContext<Context>()
       .ReplaceDefaultEntities<Data.Entities.Application, Authorization, Scope, Token, Int32>();
    
    })

    .AddServer(x => {

      x.SetAuthorizationEndpointUris("/connect/authorize")
       .SetLogoutEndpointUris("/connect/logout")
       .SetTokenEndpointUris("/connect/token")
       .SetIntrospectionEndpointUris("/connect/introspect")
       .SetUserinfoEndpointUris("/connect/userinfo");

      x.RegisterClaims(OpenIddictConstants.Claims.Email, OpenIddictConstants.Claims.Name, OpenIddictConstants.Claims.Role);

      x.RegisterScopes(OpenIddictConstants.Scopes.Profile, OpenIddictConstants.Scopes.Email, OpenIddictConstants.Scopes.Roles, OpenIddictConstants.Scopes.OfflineAccess);
      
      x.AllowAuthorizationCodeFlow()
       .AllowRefreshTokenFlow();

  x.AddDevelopmentEncryptionCertificate().AddDevelopmentSigningCertificate();

      x.UseAspNetCore()
       .EnableAuthorizationEndpointPassthrough()
       .EnableLogoutEndpointPassthrough()
       .EnableTokenEndpointPassthrough()
       .EnableUserinfoEndpointPassthrough()
       .EnableStatusCodePagesIntegration();

    })

    .AddValidation(x => {
      x.UseLocalServer();
      x.UseAspNetCore();
    });

    services
      .AddHsts(x => {
        x.Preload = true;
        x.IncludeSubDomains = true;
        x.MaxAge = TimeSpan.FromDays(1); 
    })
    .AddHttpsRedirection(x => {
       x.RedirectStatusCode = StatusCodes.Status301MovedPermanently;
    });

  services.AddMediatR(typeof(Startup));

  services.Configure<Options>(Configuration);

  services.AddScoped<IUserClaimsPrincipalFactory<User>, UserClaimsPrincipalFactory>();

} 

public void Configure(IApplicationBuilder application, IWebHostEnvironment environment) {

  application.UseHsts();
  application.UseHttpsRedirection();

  application.UseStaticFiles();

  application.UseRouting();
  application.UseCors("Cors");

  application.UseAuthentication();
  application.UseAuthorization();

  application.UseEndpoints(x => {
    x.MapDefaultControllerRoute();
  });

}
1 Answers

The best solution in this situation is to contact Workspace Support directly and provide the HAR file there.

To do this, I suggest you choose one of the options in this article here and for capturing the HAR file you can use Google's Admin Toolbox tool.

Related