damienbod / angular-auth-oidc-client

npm package for OpenID Connect, OAuth Code Flow with PKCE, Refresh tokens, Implicit Flow
https://www.npmjs.com/package/angular-auth-oidc-client
MIT License
1.14k stars 431 forks source link

Logoff is not working. No network calls, nothing in the console #1835

Open alan994 opened 1 year ago

alan994 commented 1 year ago

Hi,

First of all, I want to say thanks for building such a great library. I need help with the logoff functionality. I'm not able to log off. Here is my config and code I'm calling.

@NgModule({
    imports: [AuthModule.forRoot({
        config: {
            authWellknownEndpointUrl: 'https://cognito-idp.eu-west-1.amazonaws.com/eu-west-1_pH9tpZ2Di/.well-known/openid-configuration',
            authority: 'https://yaca-test.auth.eu-west-1.amazoncognito.com/oauth2/authorize',
            postLogoutRedirectUri: window.location.origin,
            clientId: '<my-id>',
            scope: 'openid profile email', // 'openid profile offline_access ' + your scopes
            responseType: 'code',
            silentRenew: true,
            useRefreshToken: true,
            redirectUrl: `${window.location.origin}/callback`,
            postLoginRoute: window.location.origin,
            renewTimeBeforeTokenExpiresInSeconds: 30,
            secureRoutes: ['https://localhost:7123/', 'http://localhost:5107/'],
            logLevel: LogLevel.Debug
        }
    })],
    exports: [AuthModule],
})
export class AuthConfigModule { }

My component code

public logoff() {
        this.oidcSecurityService.logoff()
            .subscribe((result) => console.log(result));
    }

What I see in the browser is null in the console and no network requests. I tried logoff and logoffAndRevokeTokens. Unfortunately, nothing seems to be working for me. Also, all data in SessionStorage is still present. I would expect data to be deleted when this method is called.

Can you tell me what I'm doing wrong here?

I checked enable token revocation in AWS Cognito identity pool app client

image

alan994 commented 1 year ago

Any idea what I'm missing here?

Sbolder commented 11 months ago

any update?

alan994 commented 11 months ago

I wasn't able to figure it out yet. I moved on with other application logic and planning to get back to it later.

Sbolder commented 11 months ago

i have found a simple workaround:

 logout() {
    //this.oidcSecurityService.logoff().subscribe((result) => console.log(result));

    window.location.href = "https://<replaceme>.amazoncognito.com/logout?client_id=<replaceme>&logout_uri=http%3A%2F%2Flocalhost%3A4200";

    // Clear session storage
    if (window.sessionStorage) {
      window.sessionStorage.clear();
    }
  }
alan994 commented 11 months ago

Tnx. I will try it. But, it would be nice to have it supported the proper way. Let's leave this one still open, until we have a proper solution

majies commented 10 months ago

Hi @alan994, i know this is a bit of an older issue now but i ran into the same thing today. Not sure if my issue will be the exact same as yours but worth checking either way.

can you run this.configurationService.getOpenIDConfigurations().subscribe(console.log); at some point after logging in and checking the config values for authWellknownEndpoints inside of the object returned from the above call.

inside it should display an object matching the interface

export interface AuthWellKnownEndpoints {
    issuer?: string;
    jwksUri?: string;
    authorizationEndpoint?: string;
    tokenEndpoint?: string;
    userInfoEndpoint?: string;
    endSessionEndpoint?: string;
    checkSessionIframe?: string;
    revocationEndpoint?: string;
    introspectionEndpoint?: string;
    parEndpoint?: string;
}

On my side i noticed that endSessionEndpoint was not being set, the reasons for this may vary but in my case it was the fact that my authority provider didn't have the exact same keys as the library was expecting. You can check the oidc config by adjusting this url https://oauth.your-authority-provider.com/.well-known/openid-configuration and looking at the return object, and check the end_session_endpoint key returned is actually called end_session_endpoint so that it will map up properly in this file below

https://github.com/damienbod/angular-auth-oidc-client/blob/d71e3bf093fd27547ef4db7e726e3794f36648d5/projects/angular-auth-oidc-client/src/lib/config/auth-well-known/auth-well-known-data.service.ts#L31

NOTE: After the Authorize call the config is saved in session storage so its worth clearning session storage while testing and trying different things

Let me know if this solves it or if its something different, happy to support and it's caused me a headache too :)

alan994 commented 10 months ago

I decided to move away from this way of doing auth and investigating options with BFF and cookie auth. I will check for this property and get back to you, but don't have ETA at the moment

fpue commented 9 months ago

I have the same issue. The aforementioned workaround worked for me. One thing to add to the suspicion of @majies: I have configured the endpoint manually, but it still does nothing via the logoff() method.

k3nsei commented 9 months ago

I have same problem. When using http loader to load configs with standalone APIs. When using static config it works ok. Problem is that getOpenIDConfigurations returns nothing but getOpenIDConfiguration returns right config. Maybe this will help to fix issue.

@damienbod @timdeschryver @FabianGosebrink

Also I would like to see sample with standalone APIs and fetching configs dynamically. Because I have suspicions that this wasn't tested and do not work.

FabianGosebrink commented 9 months ago

Can we reproduce the initial issue somehow with our samples?

k3nsei commented 9 months ago

@FabianGosebrink I will try to prepare some example project at friday. As it would be my day off from work.

mattsmasterplan commented 8 months ago

I am experiencing this exact issue as outlined in the original post. I am instead implementing an http call to my cognito service logoff endpoint and then clearing the users session as a workaround. I do not have any additional detail that has not been discussed in this thread, but would like to keep this issue active for further investigation.

ypetrovicimpactbuying commented 6 months ago

We were experiencing the exact same issue, however only on firefox.

I narrowed it down to the checkSession.

The logoff is failing here: image

The above two startCheckSession && this.checkSessionReceived are both true.

I get the feeling its due to the fact that the check session is in progress and therefor this is always returning here: image

The fact that this always returns of(null) doesn't help debugging either. The result of the logOff is always null, regardless of whether it succeeded or not..

Anyways, we solved it by calling the checkSessionService and stopping it, its private so you have to access it like this:

    this._oidSecurityService['checkSessionService'].stop();
    return this._oidSecurityService.logoff();
marianamsoares1991 commented 5 months ago

I'm experiencing exactly the same issue with the b2c as identity provider! I'm using http loader to load configs with standalone APIs and using a public route: '/callback' since all my routes are guarded.

Here is my auth config:

// Default authentication configuration
export const defaultAuthConfig: OpenIdConfiguration = {
    redirectUrl: window.location.origin + '/callback',
    postLogoutRedirectUri: window.location.origin + '/callback',
    scope: 'openid',
    responseType: 'code',
    silentRenew: true,
    historyCleanupOff: true,
    silentRenewUrl: `${window.location.origin}/app/auth.silent-refresh.html`,
    triggerAuthorizationResultEvent: true,
    autoUserInfo: false,
    logLevel: LogLevel.Debug,
    customParamsAuthRequest: {
        lang: 'FR',
    },
};

/**
 * Factory function to create an instance of StsConfigHttpLoader for loading OpenID configuration asynchronously from HTTP.
 * This function retrieves the OpenID configuration from a ConfigService and merges it with the default authentication configuration.
 * @param configService - The ConfigService instance used to load application settings.
 * @returns An instance of StsConfigHttpLoader configured with the merged authentication configuration.
 */
export const stsConfigHttpLoaderFactory = (configService: ConfigService) => {
    return new StsConfigHttpLoader(
        new Observable<OpenIdConfiguration>((subscriber) => {
            configService.load().subscribe({
                next: (settings) => {
                    subscriber.next({
                        ...defaultAuthConfig,
                        ...settings.authConfig,
                    });
                    subscriber.complete();
                },
                error: (error) => {
                    subscriber.error(error);
                    subscriber.complete();
                },
            });
        }),
    );
};

And my application config:

export const appConfig: ApplicationConfig = {
    providers: [
        // To pass the user's access token to the HTTP requests with authentication interceptor: https://angular-auth-oidc-client.com/docs/documentation/interceptors#functional-api
        provideHttpClient(withInterceptors([authInterceptor()])),
        // configure the authentication flow using angular-auth-oidc-client: https://angular-auth-oidc-client.com/docs/documentation/configuration#configure-with-standalone-config
        _provideAuth({
            loader: {
                // Load STS configuration dynamically using StsConfigLoader: https://angular-auth-oidc-client.com/docs/documentation/configuration#load-config-from-http-async
                provide: StsConfigLoader,
                useFactory: stsConfigHttpLoaderFactory,
                deps: [ConfigService],
            },
        }),
        // Initialize application configuration before the app starts
        {
            provide: APP_INITIALIZER,
            useFactory: (configService: ConfigService) => {
                return () => configService.load();
            },
            deps: [ConfigService],
            multi: true,
        },
        // Provide route configuration for the application
        provideRouter(appRoutes),
    ],
};

And finally the app routes:

export const appRoutes: Array<Route> = [
    {
        path: '',
        component: ContractsOverviewComponent,
        canActivate: [AutoLoginPartialRoutesGuard],
    },
    { path: 'callback', component: CallbackComponent }, // https://angular-auth-oidc-client.com/docs/documentation/auto-login#auto-login-when-all-routes-are-guarded
    { path: '**', redirectTo: '/' },
];

After perform the logout calling the this.oidcSecurityService.logoffAndRevokeTokens().subscribe(); I'm not being redirected to the b2c login screen and I'm being redirected to the: https://localhost:200/callback?state= ..... and redirected to my app. After that user is not logged out and I can access the user data,.

Any help ? @damienbod @timdeschryver @FabianGosebrink

alikdelrisco commented 1 month ago

+1

baptiste-gaillet commented 2 weeks ago

+1

The function logoffAndRevokeTokens do not revoke my token.

My "revocationEndpoint" is good on the config (displayed by my logs)

I have logs message when I turn to debug the lib :

A postman call on my sso revoke the token ?