10

I am getting user undefined in following code.

I have already authenticated user from MVC.

But when I use signinSilentCallback to get detail of that user, it is getting undefined using oidc-client in js.

It doesn't give any error as well.

        var mgr = new UserManager({
                    authority: "http://localhost:5000",
                    client_id: "js",
                    redirect_uri: "http://localhost:50144/signin-oidc",
                    silent_redirect_uri: "http://localhost:50144/signin-oidc",
                    response_type: "id_token token",
                    post_logout_redirect_uri: "http://localhost:50144/signout-callback-oidc",
                });

        mgr.signinSilentCallback().then(function (user) {

            //**Here user is undefined.**
            axios.defaults.headers.common['Authorization'] = "Bearer " + user.access_token;

        });

In Identityserver 4, client is defined as following.

new Client
                {
                    ClientId = "js",
                    ClientName = "js",
                    ClientUri = "http://localhost:50144",

                    AllowedGrantTypes = GrantTypes.Implicit,
                    AllowAccessTokensViaBrowser = true,
                    RequireClientSecret = false,
                    AccessTokenType = AccessTokenType.Jwt,

                    RedirectUris = 
                    {
                        "http://localhost:50144/signin-oidc",
                    },

                    PostLogoutRedirectUris = { "http://localhost:50144/signout-callback-oidc" },
                    AllowedCorsOrigins = { "http://localhost:50144" },

                    AllowedScopes =
                    {
                        IdentityServerConstants.StandardScopes.OpenId,
                        IdentityServerConstants.StandardScopes.Profile,
                        IdentityServerConstants.StandardScopes.Email
                    }
                }
Anonymous Creator
  • 2,968
  • 7
  • 31
  • 77

2 Answers2

9

signinSilentCallback: Returns promise to notify the parent window of response from the authorization endpoint. https://github.com/IdentityModel/oidc-client-js/wiki

signinSilentCallback - This is not something will return you the user object.

If you really need to get the user object on silent renew i would suggest to use this approach with folloowing code snippet. This works for me in salesforce apps as well.

this.userManager.events.addAccessTokenExpiring(() =>
            {
                this.userManager.signinSilent({scope: oidcSettings.scope, response_type: oidcSettings.response_type})
                    .then((user: CoreApi.Authentication.Interfaces.OidcClientUser) =>
                    {
                        this.handleUser(user); // This function just set the current user
                    })
                    .catch((error: Error) =>
                    {
                        this.userManager.getUser()
                            .then((user: CoreApi.Authentication.Interfaces.OidcClientUser) =>
                            {
                                this.handleUser(user);
                            });
                    });
            });

We need to handle the getUser in catch as well due to one of bug reported for iFrame in oidc-client js

From above code focus on the way the silent renew is performed when the token expires.

Sohan
  • 6,252
  • 5
  • 35
  • 56
  • 1
    My problem came as a result of the Typescript definition, which explicitly states that it is Promise: `signinSilentCallback(url?: string): Promise;`. Now I see it will never actually return a User object. Thanks for pointing this out. – codeMonkey Apr 06 '20 at 16:37
8

you can set automaticSilentRenew to true in your config

var mgr = new UserManager({
                authority: "http://localhost:5000",
                client_id: "js",
                redirect_uri: "http://localhost:50144/signin-oidc",
                silent_redirect_uri: "http://localhost:50144/signin-oidc",
                response_type: "id_token token",
                post_logout_redirect_uri: "http://localhost:50144/signout-callback-oidc",
                automaticSilentRenew: true; //here

            });

and you can use UserManager events to load the new user when the token is refreshed

this.mgr.events.addUserLoaded(args => {
  this.mgr.getUser().then(user => {
    this._user = user; // load the new user
  });
});
Fateh Mohamed
  • 20,445
  • 5
  • 43
  • 52
  • 1
    Hi, Does this `addUserLoaded()` update the details of the user profile in session Storage? – Todarmal Sep 04 '19 at 10:25
  • 1
    yes silent refresh always update the key in your session storage, addUserLoaded is an event whenever there is a new user it is triggered, (triggered after each silentrefresh) – Fateh Mohamed Sep 04 '19 at 10:47
  • I really need to test this frequently. Is there any way to lower the interval of token expiry, to get silent refresh fired up frequently? – Todarmal Sep 04 '19 at 10:56
  • yes you can change that on your identity, in the client, i think the key is called accesstoken lifetime – Fateh Mohamed Sep 04 '19 at 11:09
  • I am really caught up here, Can you please explain what do you mean by identity in the client? – Todarmal Sep 04 '19 at 11:35
  • in your identity server there is a config for each client, you can modify access tken life time there – Fateh Mohamed Sep 04 '19 at 12:44
  • I struggled with this for a good while until I started handling the UserLoaded event, setting the new user object to my controller's field. Following the examples and guides from the OIDC Client Wiki excactly to the point didn't do much good actually, since they fail to mention anything like this - unless I'm being dumb and blind here :) Cheers! – haugan Dec 09 '19 at 11:28
  • 6
    Just wanted to add a quick comment that the authors of `oidc-client` recommend against using `automaticSilentRenew` and regret adding it to the library at all. The recommended approach is as set out in the accepted answer to this question. This comment is for people Googling how to go about implementing this stuff. I note that this answer was probably posted before the authors expressed their thoughts about `automaticSilentRenew`. – onefootswill Jan 20 '20 at 23:44
  • @onefootswill Do you have a link to an article or something that explains more about why the automaticSilentRenew is bad, and where the authors express their thoughts about it? – SnorreDan Mar 03 '20 at 07:27
  • 4
    @SnorreDan Take a look at this comment on this GIT issue https://github.com/IdentityModel/oidc-client-js/issues/612#issuecomment-404825555 The comment was made by the author. – onefootswill Mar 03 '20 at 10:23