Oidc-client-js: UserManager.signinSilent() does not include the id_token_hint. Please include it.

Created on 24 Sep 2016  路  27Comments  路  Source: IdentityModel/oidc-client-js

Some authorization servers require the id_token_hint.

enhancement

Most helpful comment

done. 1.2.0-beta.6 pushed to npm

All 27 comments

I can see your request, as the spec says:

When possible, an id_token_hint SHOULD be present when prompt=none is used and an invalid_request error MAY be returned if it is not; however, the server SHOULD respond successfully when possible, even if it is not present.

So did you open an issue for "some authorization server" to allow the absence of id_token_hint?

@brockallen Thank you for looking into the spec. I have opened an issue with OpenIddict and have learned that it might be covered by https://github.com/openiddict/openiddict-core/issues/17 too.

I thought about this some more, and the OP should allow not passing because the client might only being using response_type of "token" (rather than "id_token token"). The only use of the client passing it is to ensure that the current session matches the id_token_hint. oidc-client-js already does this check client-side.

Also, I admit the spec is not at all definitive on who should be doing what, as the wording is self-contradictory IMO.

Also, not sure that's the right issue.

BTW, for now you can pass id_token_hint explicitly to the various signin methods.

Given that you can explicitly pass the id_token_hint for the OP you're using as a workaround, I'm not inclined to change it here. I don't like that the URL is bloated with the additional overhead (which admittedly is a minor grievance) , but really the OP/AS should allow it because the client might only be using OAuth2 (and not OIDC).

My 2 cents:

but really the OP/AS should allow it because the client might only be using OAuth2 (and not OIDC).

prompt=none is totally OpenID Connect-specific, it doesn't exist in the OAuth2 spec. Yet, response_type=token is not a "valid" response type in OIDC (though I'm pretty sure most implementations treat it as a valid one for backcompat' reasons):

NOTE: While OAuth 2.0 also defines the token Response Type value for the Implicit Flow, OpenID Connect does not use this Response Type, since no ID Token would be returned.

So the chances of having a prompt=none request without any identity token seem pretty low to me.

And anyway, it doesn't change anything to the fact the client is encouraged to send an id_token_hint when it can by the OIDC specification (just like the OP should accept a request that doesn't specify it, I agree with you).

I think you understand my point -- it's legal for an OAuth2 client to use an iframe to renew the access token, thus the expectation that an OP/AS would/should accept the request without an id_token.

Sure, I do. But our point is that oidc-client should send the identity token when it knows it. Of course, this must not throw when no identity token is available, since id_token_hint is an optional parameter, which shouldn't prevent the response_type=token scenario from working.

done. 1.2.0-beta.6 pushed to npm

Thanks @brockallen! :clap:

I've upgrade to 1.2.0. After having logged in to the OP, I open a new tab and refresh the page, calling signinSilent(). The request does not include the id_token_hint. It includes the following parameters.

http://localhost:12345/connect/authorize
?client_id=Aurelia.OpenIdConnect
&redirect_uri=http%3A%2F%2Flocalhost%3A9000%2Fsignin-oidc
&response_type=id_token%20token
&scope=openid%20email%20roles%20profile
&state=10963900f9d14ed9b490968bb53f8520
&nonce=87d3d29e07d044489e3f59edde29ec62
&prompt=none

new tabs don't share state (by default) from other tabs. by default sessionStorage is used.

I am not sure then how I can keep the user signed in across tabs. Using localStorage is discouraged, and an id_token_hint is not available for prompt=none.

so do a normal authorization redirect to the OP

Hmm. That would be an unpleasant experience for the end-user. As an end-user, I expect to stay logged in to the client across windows/tabs. Aha. I think I see what you mean. The OP will not ask for interaction on a normal redirect in the case that the end user is already logged in there. Is that right?

so then do a silent redirect and use a OP that supports that

Thank you for the clear guidance. I think that I understand the options now.

  1. Use localStorage.
  2. Use normal authorization redirect.
  3. Use silent redirect with OP that supports that.

SSO is not magic. any server-side app would do the redirect approach. you say that it's not nice for users, so JS clients have the advantage that they can easily use iframe to achieve it. get open addict to support it if that's the OP you want to use it.

any server-side app would do the redirect approach

I thought that a server-side app would store the login in a cookie, which would persist across tabs.

ok, i misunderstood about the JS clients -- i assumed you meant different clients. in different server-side clients since they'd normally use different authN cookies, they'd then normally expect to do a redirect to signin.

so then let's focus on the same JS client run twice. web apps just work differently since they do share cookes across tabs. JS/SPA apps don't, of course. the mechanics are different. if you don't have PII issues, then use localStorage to store your data across tabs.

Got it. That makes sense. I am currently working on using localStorage instead of sessionStorage, because I feel pretty chilled about the PII stuff. It looks like we can pass it into the ctor, which seems very convenient. https://github.com/IdentityModel/oidc-client-js/blob/dev/src/WebStorageStateStore.js#L8

So there is something that I am not understanding. I am able to call the ctor of the UserManager but not of the UserManagerSettings nor of the WebStorageStateStore. Are the latter two protected in a way that the former is not? I am using TypeScript 2.0.

    let um = new UserManager({}); // works
    let ums1 = new UserManagerSettings(); // unable to find name
    let ums2 = <UserManagerSettings> {}; // works

This works for me:

var config = {
            authority: "http://localhost:1941/",
            client_id: "js_oidc",
            redirect_uri: window.location.protocol + "//" + window.location.host + "/index.html",
            post_logout_redirect_uri: window.location.protocol + "//" + window.location.host + "/index.html",

            // these two will be done dynamically from the buttons clicked, but are
            // needed if you want to use the silent_renew
            response_type: "id_token token",
            scope: "openid profile email api1 api2",

            // this will toggle if profile endpoint is used
            loadUserInfo: true,

            // silent renew will get a new access_token via an iframe 
            // just prior to the old access_token expiring (60 seconds prior)
            silent_redirect_uri: window.location.protocol + "//" + window.location.host + "/silent_renew.html",
            automaticSilentRenew: false,

            // this will allow all the OIDC protocol claims to be visible in the window. normally a client app 
            // wouldn't care about them or want them taking up space
            filterProtocolClaims: false,

            // use localStorage
            userStore: new Oidc.WebStorageStateStore({ store: window.localStorage })
        };
var mgr = new Oidc.UserManager(config);

Oddly enough, the TypeScript compiler cannot find WebStorageStateStore({}) nor Oidc.WebStorageStateStore({}) but it is able to cast to them.

If the .ts file needs fixing, please send a PR. Also, as a matter of github protocol, please open new issues for new issues.

Just a FYI for anyone else running into the same issue we had:
Because of the inclusion of id_token_hint in the url, depending on the length of the token, the url could exceed the 2048 url limit, which broke our site for certain users.
Even though this change was implemented as a 'minor' update, for us it was a breaking change.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

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

wsimf picture wsimf  路  4Comments

baoduy picture baoduy  路  4Comments

rmja picture rmja  路  3Comments

LEW21 picture LEW21  路  4Comments