Closed shaunluttin closed 8 years ago
And this didn't happen from just refreshing the page when the OIDC response is still in the URL?
No... I fixed that already:
public LoginRedirectHandler = (): Promise<any> => {
this.logger.Debug("LoginRedirectHandler");
return this.UserManager.getUser().then((user) => {
// avoid page refresh errors
if (user === null || user === undefined) {
return this.UserManager.signinRedirectCallback(null);
}
});
}
I think the problem was that my localhost client was redirecting to the live demo. If I am not mistaken, this is exactly what the state
is supposed to prevent. #learning
state RECOMMENDED. Opaque value used to maintain state between the request and the callback. Typically, Cross-Site Request Forgery (CSRF, XSRF) mitigation is done by cryptographically binding the value of this parameter with a browser cookie.
Ok, so then all set on this issue?
Sure. If it recurs I will let you know and reopen it.
Reopening. It occurred on the live demo. I will continue to look into it.
https://zamboni-app.azurewebsites.net/signin-oidc#state=b239e2c58bf1477a9b0f3f085a80724e&token_type=Bearer&access_token=CfDJ8IB6Zwu1nABHl0l0t5mCtQy92cT2Hp8T9xVLJj1FCgAa-IbmyG3G4pI_6yUbQL1FZHjf1Eu9NaQA3kY7T_yWOr0nfS9yGhWmAzvt9vR7QB-T-lmzY4bAOoE1gsO3KYpAnbBk4oDnGypPL184-jJ1MGNhPMWGaMSuSqZSOvsLypusP67GrfOLrVm2rYo7Y3LWzUg07oEzgUCmHpEHvhECMreJLUoxnaxJlgbtaIvyfGmxbgKBxxydJ0TwwINvMYT0N-4SR1bggNx6yXRz0kC5TKm6BHRkdr-bJbWuX3y5101_snhGz4b7yLSblzddKGMnWil7eApSk4HMJwjnkPyiYId5oeUWBVAW4bdpW7xFY3JdMVFhMlr6jd4VFTtMwPayV8TD72iZkqhA9A3h5DQCipnpH0yqjZn4F_km7KRuCVzqqDeyLRR6VCc7nsoM1svwZDg0l_QlpwNi9IHqMDFmS3OpGRzHWAeWchif3iAevqATFKb9Pphc3NKCFqeMI3OCLV2MBzFeA7kb5YmG9CC4BWM_GJUU8QtzXeWK-hy-mNLjJxjk9M2cLTh2sVcXINgsR_Df-eSvIkhddBgbJEcA0BWqu9rPtVc73Hk_3qbKJEe3evPwgi6VpXQZZgy7qWznDbZpIptiz-TYGwkH9kHKCOUNxYM09GInBQxuEEG4xWWI--Zd-0-3TqSnITesSGCjtNAB1L3JtAnWuQlDexdYy1LixcgHX_pudPB1oaGMwOt_l20XvrcKtjr8iN3FAXtiNufndkb3oRwPmNM4GFvE9G0WCob3UShI6QxW76122lOwmU5akXo4yu4BOo095llrmkiU3Vn0AQXxkVbntGuNru6qyqRaA0i2Er3s8fMg9X6Djp7bpNGi1tv_jSM6R2yoNAn7hT7J7kHZvF1IVRTvMi8IOfXtMb-rCAX3n1RLAT4OE0kHN8yOak7I6FKjgVMPToyfsXQHypyepQvi1C-i_YjIVtsagCA1qIQEMVn6n3PqBcnzZjkFYt3yFlbYysZlwhEpiqFKYeywGKNiGshSs50GpKBQ2UPSzwpuJ1mYh_sVYCyplfdtT5xZ9N_pJvRbwFu_iwDTQZCG92jcFAWTekMKAEohF5eS0TMrM98wJBJl8yH5Exo-pfVtWdb8o7exbG4BAgl-XjeChk9gEuGw_Dpj4lF6a7nGtGpkj5LL4IDNX4R-75dA9yjgUy4OmtnIMJOCXJI1A8aY7jLaP0I9Q8yTn-31rYfkgawnCAYf4FHTbjeXPiy3ZIci2XKWPpScDg&expires_in=1800&id_token=eyJhbGciOiJSUzI1NiIsImtpZCI6IjlLVzdPNzRTWEZHRUlVRTlOVFRXRlNYTVVRTEZRUVBCUVJFWFhKWTIiLCJ0eXAiOiJKV1QifQ.eyJ1bmlxdWVfbmFtZSI6InNoYXVuQGJpZ2ZvbnQuY2EiLCJlbWFpbCI6InNoYXVuQGJpZ2ZvbnQuY2EiLCJBc3BOZXQuSWRlbnRpdHkuU2VjdXJpdHlTdGFtcCI6IjcyZjcxZDVlLWJhYTAtNGNmNC04NTZkLWFhNTE5ZDMwMWVkMCIsInN1YiI6IjkxM2RiY2JlLTNlNGQtNDU0My04ZDk4LTQwMTJhYjU2YWRiYSIsImp0aSI6ImM2NzI5ZmU0LTA0NjMtNDE0MC1iMTc4LTI4MzFiYzA0ZmI5ZCIsInVzYWdlIjoiaWRfdG9rZW4iLCJhdWQiOiJBdXJlbGlhLk9pZGNDbGllbnRKcyIsIm5vbmNlIjoiMmE0ZjcxNzY2ODQ5NDI0NTllNzAwN2JjZmQ0ZTJmZjQiLCJhdF9oYXNoIjoiZDRZWGpCa3RCbzlmeS1Ndk1sQ0ZjdyIsImF6cCI6IkF1cmVsaWEuT2lkY0NsaWVudEpzIiwibmJmIjoxNDcyMjUwODE4LCJleHAiOjE0NzIyNTIwMTgsImlhdCI6MTQ3MjI1MDgxOCwiaXNzIjoiaHR0cHM6Ly96YW1ib25pLWF1dGguYXp1cmV3ZWJzaXRlcy5uZXQvIn0.itkAcWOa4AgMdV77wN9O8hZe3sWatX0QikCirmIt-XHvJGUkct5B6VzUHmPcDuo9nb18OM_lLeOXJtyW7NKvLRoRiClMXkCTll-DPxvSWkoz3kj0yiny4l7HU9Qamhxc1pzqCyKVXOSxU9pPBK0bprY2o5KT4G_VJLAXz8PwBMTz0eig1Ao2Fkgj3F3FabRDFWi0I_PG2cKVMkKyIGhVqWBRMfBbXGumjlUmLEbE_CTaD4PB_79MaPFu2fASDxRm661Irh9MrB9UOsTvTFbXNYZwyM6xmOaII2cIlm1ceyQhtpPv-eGApeor94Xypt8OH3UabZYrOQZ02Cnhe2cINw
public LoginRedirectHandler = (): Promise<any> => {
return this.UserManager.getUser().then((user) => {
// avoid page refresh errors
if (user === null || user === undefined) {
return this.UserManager.signinRedirectCallback(null);
}
});
}
oidc.106f050d7dd9447496be88e65dd5709c
{
"authority" : "https://zamboni-auth.azurewebsites.net",
"client_id" : "Aurelia.OidcClientJs",
"created" : 1472197937,
"id" : "106f050d7dd9447496be88e65dd5709c",
"nonce" : "930bb9b5d17043dd96d29748d3d42dd7"
}
oidc.4c1b15344c8b44e3bbadac6da89d4820
{
"authority" : "https://zamboni-auth.azurewebsites.net",
"client_id" : "Aurelia.OidcClientJs",
"created" : 1472198303,
"id" : "4c1b15344c8b44e3bbadac6da89d4820",
"nonce" : "6a7b2b1136a748eabb2184bb606855e7"
}
It now seems to be associated with getUser
returning null even when there is one or more oidc.4c1b15344c8b44e3bbadac6da89d4820
keys in storage as above.
Correction - those values do not represent the user. They are something else.
Perhaps this issue makes me want to think about a diagnostics API to read what's present in storage...
Hmm. I don't understand. What do you mean?
Hmm. Cannot we already do that with the dev tools in Firefox/Chrome/Etc?
Why did we change this to question? It seems to be a bug. What am I missing?
I thought it was because you didn't trigger the authorization request from the same app that was receiving the authorization callback?
That was an initial suspicion. It turns out to be something else that I haven't yet isolated. Here is where it keeps occurring about 75% of the time:
https://zamboni-app.azurewebsites.net
Enable logging, and keep digging. If there's no state, then it means that either the state never persisted, or it's getting purged before the user returns to the client.
It's also happening with a LIVE version of your oidc-client-js sample here:
https://zamboni-oidc.azurewebsites.net
@PinpointTownes Maybe it has something to do with the way I have configured the OpenIddict server.
If it's working some of the time, then I'm thinking it's a storage issue on the client. I'd suggest checking to see if the localstorage is written before you redirect, and then check to see if it's still there when you come back. IIRC, the state param value is the key for the storage.
Steps to reproduce:
start signin main window
end signin main window
Error: No matching state found in storage
. This occurs about 1/2 the time.
Is there a state param being returned from that workflow?
I'm checking now. I've set breakpoints here and am looking:
Where in the code are you expecting to see a state param return?
Well, I tried it and it worked. :/
Yup. It's a sometimes thing. :\
So, just now at line 20 in WebStorageStateStore.js, which I think it the ultimate step before redirect, this is the contents of Local Storage:
oidc.47a8774d6c484d9bb7ac1cfda4b1be78
{ "authority" : "https://zamboni-auth.azurewebsites.net",
"client_id" : "OidcClientJs.UserManager",
"created" : 1472683985,
"data" : "some data",
"id" : "47a8774d6c484d9bb7ac1cfda4b1be78",
"nonce" : "8f949c5de6ea4e719379e9d8784353d8"
}
In other words, there is no state
. Is that expected?
The state is the id of the entry in localStorage.
I wonder if you're filling your localStorage. Do you have a ton of localStorage entries with the key starting with "oidc"? If so, then hit the "clear stale state" button in the UI.
Nope. There is only that one item, because I am using a new private window for each attempt to reproduce. The only entry I am seeing is oidc.47a8774d6c484d9bb7ac1cfda4b1be78
. Brainstorm: could there be some race condition with the redirect and the promises?
Something is happening here in OidcClient.js This is where is sets the state that is going to look for later by state.id
.
79 return stateStore.set(state.id, state.toStorageString()).then(() => {
80 return request;
81 });
Okay. Based on your suggestion about stale state, I am going to try the following. Please let me know if it doesn't seem sensible for some reason.
public Login() {
// prevent Error: No matching state found in storage,
// which can happen due to duplicate state entries
this.UserManager.clearStaleState(null).then(() => {
let args: any = {};
this.UserManager.signinRedirect(args);
});
}
clearStaleState
should be used within an app to cleanup stale stuff. If a user does not complete the sign in process, then those state entries can pile up. That's what this API is for. I imagine only someone doing a demo would ever really run into this as frequently as you are (if this is in fact the issue, which I'm not yet sure of).
Let me know if this seems to clear it up.
I'm afraid the problem is still occurring. It's mighty odd that you aren't able to reproduce it, because it's happening now with great frequency. Tomorrow I will again try to isolate this beast.
https://zamboni-app.azurewebsites.net
@PinpointTownes Maybe it has something to do with the way I have configured the OpenIddict server.
That's not impossible, tho that's the first time I hear someone having a problem with the state
thingy.
FYI, I'm not able to reproduce this issue. The only case where I get a No matching state found in storage
error is when clicking too early on the end signin main window
button (i.e before the redirection completes, 'cause the OIDC payload is not the URL fragment yet when doing that)
Does it take longer than 60 seconds for the user to return to the client? Also, are you calling clearStaleState a lot? Calling clearStaleState will purge state entries from the client storage that are older than 60 seconds. You can change this via the staleStateAge setting. Maybe a default of 5 or 10 minutes would better...
Yes. Sometimes it does take longer than 60 seconds for the user to return to the client. No. I am only calling clearStaleState prior to sending the user to the authorization server.
I've put a breakpoint here:
g.set(S.id, S.toStorageString()).then(function() {
return m // breakpoint here
})
...at which point there is one and only one item in localStorage.
On return from the authorization server, though, it is gone.
New more comprehensive steps to reproduce:
OMG. The penny just dropped. LocalStorage differs between:
That is why it was only happening sometimes. Sometimes I started the use case with HTTPS; othertimes with HTTP.
Ok, all set then on this issue?
Yup. Thank you for the help.
Hello, I am facing the same issue. Could you please share me steps to investigate and fix it? Thanks
I am having the same problem, I figured out that the problem is intermitent but always related to http - https redirection.
I open the web app in a new brand installation of Firefox with incognito mode, go through http, get redirected by cloudfront to sso and after login get redirected to https. Just some times, it throw the error and refreshing disappear. it's really hard to reproduce.
I even added a condition to check the protocol url and remove localStorage if it's under http, but still same error.
Have no many ideas more, @shaunluttin can you help here? do you support both requests? http & https?
I am sure that if I only support https, there will be no error but I need both.
Thanks,
If the user starts on http on your app and that triggers login to the token server and it's configured to send you back to https, it won't work. You need to make your http page redirect to your own https page, then start the login process.
Hi @brockallen thanks for replying.
If the user tries on http, it should get 301 and get redirected, as configured that in aws. See this img:
so, curl to http -> error page, no js library, curl to https -> my app.
do you have any idea what could be happening? I am open to try ideas :)
Thanks,
I was receiving the same error, which in my case related to not having provided the key to unlock the pfx which contained my signing key.
In my case the dev dialog to supply the key was being popped on another desktop, (in win 10, you can have multiple desktops) so i didn't see it and things subsequently broke, I can imagine in other setups some other form of masking is occuring that is preventing devs from realizing that they are not providing a signing key or access to whatever container they are using to hold the signing key. HTH.
I have the same error, using react-oidc and an azure appservice webapp. I configured http-only in azure, so this seems not to be the problem. But @intermension could you elaborate some more on this? This bugs us for multiple days now, and no clue what the solution could be.
@Pinguwien Hope you sorted this in the meantime. The tokens are issued by an authority (your IDS4 instance). When the client checks the token it checks the signature to make sure it was issued by an authority it trusts.
In my case the authority (my IDS4 instance) could not access the token signing key, i had stored in an X509 certificate, because that certificate was in a password protected PFX files and i did not provide the IDS4 the password. Without a password to the PFX it could not sign the token and so things broke..
We are also experiencing this @Pinguwien @intermension with vuex-oidc package and using Azure App Service...
Could this IdentityServer 4 related SO question be a hint?
This is because of the time mismatch between system time and that region time.
System time should not be more than five minutes different than the actual regional time. It can be off by showing up to five minutes earlier or up to five minutes later than regional time.
This issue got fixed once the system time is corrected.
I've been troubleshooting an issue to do with configuring a state store for the last few days and feel like it might be worth adding my voice to this discussion.
While I think in every case, there is going to be nuance, the one thing that I can say is that I have a working user store on the exact same UserManager
instance. My origin is exactly the same both outbound for the redirect and inbound after the server sends me back.
It's almost as if UserManager
is just outright ignoring the StateStore implementation I'm providing it?
One of users got this error, and just as @ux-engineer mentioned it was due to their system time being a little over 5min off from the server's time. Why it gave this error in particular, I am not sure... but correcting the user's system time fixed the login problems.
Steps to Reproduce
This error seems to happen after being logged in for a while, and then trying to login again, perhaps after the login has expired. Apologies for not having more details.
Stack Trace