DuendeSoftware / Support

Support for Duende Software products
21 stars 0 forks source link

Unable to signout of external idp provider #1437

Closed ian-malvi closed 1 month ago

ian-malvi commented 1 month ago

Which version of Duende IdentityServer are you using? 7.0.6

Which version of .NET are you using? .Net 8

Describe the bug

We have created Identity server to authenticate web api from Angular application. We are using external idp provider and local idp for login.

User can login and logout using both external and local idp fine. But When logout using external idp, it logout user from identity server but not from external idp.

Existing flow

When user hit web url it redirect to identity server login page url if user not logged in. User will enter email id and submit on login page, It redirect to external idp login page page. after successfully login in external idp it redirect to web url (Angular SPA).

When user click on logout it redirected to identity server login page without logout from external idp. It should be logout from identity server and external idp both.

We have configurations as below.

Identity Server startup configurations

    var identityBuilder = builder.Services
        .AddIdentityServer(options =>
        {
            options.KeyManagement.Enabled = false;
            options.LicenseKey = licenseKey;
        })
        .AddProfileService<CustomProfileService>()
        .AddConfigurationStore(options =>
        {
            options.ConfigureDbContext = b => b.UseSqlServer(isConfigConnection,
                sql => sql.MigrationsAssembly(migrationsAssembly));
        })
        .AddOperationalStore(options =>
        {
            options.ConfigureDbContext = b => b.UseSqlServer(isConfigConnection,
                sql => sql.MigrationsAssembly(migrationsAssembly));
            options.EnableTokenCleanup = true;
            options.TokenCleanupInterval = 3600;
        });

    // Signing credential
    if (builder.Environment.IsDevelopment())
        identityBuilder.AddDeveloperSigningCredential();
    else
        identityBuilder.AddSigningCredential("CN=IdsvCertificate");

    var authenticationBuilder = services.AddAuthentication();

    authenticationBuilder
        .AddSaml2("ExternalSSO", "ExternalSSO", options =>
        {
            options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
            options.SPOptions.EntityId = new EntityId(samlHost);
            options.SPOptions.ModulePath = moduleUrl;
            options.IdentityProviders.Add(new IdentityProvider(new EntityId(samlApplication.SamlConfiguration?.IdpEntityId), options.SPOptions)
            {
                MetadataLocation = samlApplication.SamlConfiguration?.MetadataLocation,
            });
            options.SPOptions.ServiceCertificates.Add(certificate);
        });

Web API startup configurations

    services.AddAuthentication("token")
        .AddJwtBearer("token", options =>
        {
            // base-address of your identityserver
            options.Authority = Configuration.GetSection("ApplicationSettings:IdentityServiceUrl").Value;
            options.Audience = "myApi";

            options.TokenValidationParameters.ValidTypes = new[] { "at+jwt" };

            // if token does not contain a dot, it is a reference token
            options.ForwardDefaultSelector = ForwardReferenceToken("introspection");
        })
        .AddOAuth2Introspection("introspection", options =>
        {
            // base-address of your identityserver
            options.Authority = Configuration.GetSection("ApplicationSettings:IdentityServiceUrl").Value;

            // this maps to the API resource name and secret
            options.ClientId = "myApi";
            options.ClientSecret = "myClientSecretkey";
        });

Angular configurations

We are using oidc-client - ^1.11.5 package in angular

private _userManager: UserManager;

private get idpSettings(): UserManagerSettings { return { authority: environment.idpAuthority, client_id: environment.clientId, redirect_uri: ${environment.clientRoot}/signin-callback, scope: "openid profile myApi", response_type: "code", post_logout_redirect_uri: ${environment.clientRoot}/signout-callback, automaticSilentRenew: true, silent_redirect_uri: ${environment.clientRoot}/silent-callback.html, client_secret: environment.clientSecret, } }

constructor() { this._userManager = new UserManager(this.idpSettings); }

public login = (returnUrl?: string) => { return this._userManager.signinRedirect(); }

public logout = () => { this._userManager.signoutRedirect(); }

RolandGuijt commented 1 month ago

It looks like you're using the Sustainsys Saml2 library to configure the external identity provider. A successful logout with that requires a significant number of parameters which all have to be set correctly. Please enable logging and look for this log entry.

If that doesn't help you with figuring out the problem, please open an issue at Sustainsys' issue tracker.

ian-malvi commented 1 month ago

Thank you @RolandGuijt

Yes, We had missing claims details there. I appreciate you for this.