8

I have cloned the repo from the redux-oidc-example and it works for the most part but after a few hours it gives the following error:

Action payload: ErrorResponse: login_required
at new e (oidc-client.min.js:1)
at t [as _processSigninParams] (oidc-client.min.js:1)
at t [as validateSigninResponse] (oidc-client.min.js:1)
at oidc-client.min.js:1

UserManager.js looks like this:

const userManagerConfig = {
  client_id: 'js.dev',
  client_secret: 'secret',
  redirect_uri: `${window.location.protocol}//${window.location.hostname}${window.location.port ? `:${window.location.port}` : ''}/callback`,
  response_type: 'id_token token',
  scope: 'openid email profile role offline_access',
  authority: 'http://localhost:8080',
  silent_redirect_uri: `${window.location.protocol}//${window.location.hostname}${window.location.port ? `:${window.location.port}` : ''}/silent_renew.html`,
  automaticSilentRenew: true,
  filterProtocolClaims: true,
  loadUserInfo: true
};

and my identity server config:

{
        "Enabled": true,
        "ClientId": "js.dev",
        "ClientName": "Javascript Client",
        "ClientSecrets": [ { "Value": "K7gNU3sdo+OL0wNhqoVWhr3g6s1xYv72ol/pe/Unols=" } ],
        "AllowedGrantTypes": [ "implicit", "authorization_code" ],
        "AllowedScopes": [ "openid", "email", "profile", "role", "offline_access" ],
        "AllowOfflineAccess": true,
        "AllowAccessTokensViaBrowser":true,
        "RedirectUris": [
          "http://localhost:8081/callback",
          "http://localhost:8081/silent_renew.html"
        ],
        "PostLogoutRedirectUris": [
          "http://localhost:8081"
        ],
        "AccessTokenLifetime": 900,
        "RequireConsent": false
      }

I noticed that prior to error last valid response had one cookie response(idsrv.session) with empty value with the expiry date set to the previous year:

idsrv.session cookie

I believe this to be the root cause of the issue, I searched it on related Github repo and tried to add the Cookie.SameSite to none but it didn't help:

services.AddAuthentication()
                .AddSaml(Configuration,externalProviders.UseSaml)
                .AddCookie(options => {
                    options.SlidingExpiration = true;
                    options.ExpireTimeSpan = TimeSpan.FromDays(30);
                    options.Cookie.SameSite = SameSiteMode.None;
                });

Any idea!

Attiqe
  • 646
  • 1
  • 10
  • 22

4 Answers4

8

This is likely due to your IDP session expiring - if you call the authorize endpoint with prompt=none but it's unable to satisfy that request because no valid session exists (i.e. authentication cookie does not exist or has expired) then it will return error=login_required.

If this occurs then the correct course of action is to do an interactive (i.e. prompt=login) sign in request in the top level browser window.

mackie
  • 4,996
  • 1
  • 17
  • 17
4

After searching the Identity Server 4 repo, I made the following changes to my code:

services.AddIdentityServer(options=>
                {
                    options.Authentication.CookieLifetime = TimeSpan.FromDays(30);
                    options.Authentication.CookieSlidingExpiration = true;
                })
                .AddProfileService<ProfileService>()
                .AddSigningCertificate(Configuration)
                .AddInMemoryClients(Configuration.GetSection("IdentityServer:Clients"))
                .AddInMemoryIdentityResources(Resources.GetIdentityResources());

It started working afterward, but you would have to login again after you close the browser or reopen a new tab I guess it's because of the sessionStorage.

Attiqe
  • 646
  • 1
  • 10
  • 22
  • I'm having the same issue. Did you manage to finally solve your issue ? – Enrico Massone Sep 15 '20 at 13:34
  • can you please report your entire ConfigureServices method ? If you prefer you can comment my own question https://stackoverflow.com/questions/63901667/oidc-client-js-silent-access-token-renew-breaks-because-identity-server-authent – Enrico Massone Sep 15 '20 at 13:37
  • 1
    Sure, I don't there is enough space to enter here I will post on your question. – Attiqe Sep 15 '20 at 13:39
0

When the session expires the signin-callback is being called by STS having a query parameter called 'error' with the value 'login_required'.

In the signin-callback, before completing sign-in, you can check for this query parameter and if it's found you can sign-out also from your web client.

Screenshot of network requests to authorize and signin-callback endpoints

Tim
  • 5,435
  • 7
  • 42
  • 62
Rami
  • 35
  • 1
  • 5
0

I had the same issue and tried the proposed above, but for me, it actually was SameSiteMode not set correctly on IdentityServer Cookies. It caused Callback error: ErrorResponse: login_required right after login and after N attempts user was logged out.

This helped me https://github.com/IdentityServer/IdentityServer4/blob/main/src/IdentityServer4/host/Extensions/SameSiteHandlingExtensions.cs

What they do is based on this article https://devblogs.microsoft.com/dotnet/upcoming-samesite-cookie-changes-in-asp-net-and-asp-net-core/

Hope this is useful.

Update.

I had another issue related to this when the user was logged out after re-opening a browser (especially on Android Chrome). login_required error was shown. I noticed that session cookie Expires/Max-Age was set to Session and not some future date. Probably because of that check session iframe (with src={identity server url}/connect/checksession) failed as Identity Server thought there was no session as cookie expired. I tried setting cookie lifetime via options, but it didn't work as expected for some reason. Lifetime was always 14 days:

services.AddIdentityServer(options=>
  options.Authentication.CookieLifetime = TimeSpan.FromDays(30);
  options.Authentication.CookieSlidingExpiration = true;
})

Then I tried this and it worked for me:

services.ConfigureApplicationCookie(options => {
   options.ExpireTimeSpan = sessionCookieLifetime;
   options.SlidingExpiration = true;
})
Vadym Berkut
  • 148
  • 1
  • 7