Oidc-client-js: Oidc client with Google OAuth implicitflow signout issue

Created on 11 Sep 2018  路  2Comments  路  Source: IdentityModel/oidc-client-js

Issue: In my angular app, when user clicks on logout button, following code gets called:

<button *ngIf="isLoggedin()" (click)="authService.logout()">Logout</button>

Implementation of AuthService.logout

  logout(): Promise<any> {
      return this._userManager.signoutRedirect();
  }

AuthService constructor:

  constructor(private httpClient: HttpClient, private router: Router) {
    var config = {
      authority: Constants.stsAuthority,
      client_id: Constants.clientId,
      redirect_uri: '${Constants.clientRoot}assets/oidc-login-redirect.html',
      scope: 'openid profile',
      response_type: 'id_token token',
      post_logout_redirect_uri: '${Constants.clientRoot}?postLogout=true',
      userStore: new WebStorageStateStore({ store: window.localStorage }),
    };
    this._userManager = new UserManager(config);
    this._userManager.getUser().then(user => {
      if (user && !user.expired) {
        this._user = user;
      }
    });
  }

Above call is throwing the following exception:
OidcClient.createSignoutRequest: No end session endpoint url returned

Upon some research, it seems like When userManager.signoutRedirect is called, it is internally calling methods which endup in the below call in oidc-client.js:

However, end_session_endpoint is not in the metadata of some of popular oauth providers and this method throws exception. Think this parameter should be made optional.

    OidcClient.prototype.createSignoutRequest = function createSignoutRequest() {
        var _this3 = this;

        var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
            id_token_hint = _ref2.id_token_hint,
            data = _ref2.data,
            state = _ref2.state,
            post_logout_redirect_uri = _ref2.post_logout_redirect_uri;

        var stateStore = arguments[1];

        _Log.Log.debug("OidcClient.createSignoutRequest");

        post_logout_redirect_uri = post_logout_redirect_uri || this._settings.post_logout_redirect_uri;

        return this._metadataService.getEndSessionEndpoint().then(function (url) {
            if (!url) {
                _Log.Log.error("OidcClient.createSignoutRequest: No end session endpoint url returned");
                throw new Error("no end session endpoint");
            }

            _Log.Log.debug("OidcClient.createSignoutRequest: Received end session endpoint", url);

            var request = new _SignoutRequest.SignoutRequest({
                url: url,
                id_token_hint: id_token_hint,
                post_logout_redirect_uri: post_logout_redirect_uri,
                data: data || state
            });

            var signoutState = request.state;
            if (signoutState) {
                _Log.Log.debug("OidcClient.createSignoutRequest: Signout request has state to persist");

                stateStore = stateStore || _this3._stateStore;
                stateStore.set(signoutState.id, signoutState.toStorageString());
            }

            return request;
        });
    };

Here is more discussion on this for google: Similar Github Issue at https://github.com/openid/AppAuth-iOS/issues/47

There should be an option to just clear local storage and let user stay signed in for the provider unless the provider supports signing out just for this client.

question

Most helpful comment

You can work around this issue by manually adding the end_session_endpoint metadata property in addition to the required settings

const userManager = new UserManager({
  // ...,
  post_logout_redirect_url: 'http://localhost:3000/login',
  metadata: {
    // ...,
    end_session_endpoint: 'http://localhost:3000/logout/callback', // Or however you want to clear sessionStorage or revoke the token
  },
});

All 2 comments

OidcClient.createSignoutRequest: No end session endpoint url returned

Sounds like your token server doesn't support signout.

You can work around this issue by manually adding the end_session_endpoint metadata property in addition to the required settings

const userManager = new UserManager({
  // ...,
  post_logout_redirect_url: 'http://localhost:3000/login',
  metadata: {
    // ...,
    end_session_endpoint: 'http://localhost:3000/logout/callback', // Or however you want to clear sessionStorage or revoke the token
  },
});
Was this page helpful?
0 / 5 - 0 ratings

Related issues

pottabathini picture pottabathini  路  5Comments

iXmonvi33 picture iXmonvi33  路  4Comments

m-andrew-albright picture m-andrew-albright  路  5Comments

dotli picture dotli  路  3Comments

wsimf picture wsimf  路  4Comments