what I understood is- oidc-client generates nonce and state and sends it to an authorization server(Identity server 4). This is used to prevent CSRF attack, replay attack.
State and nonce are sent through signinredirect() sample example below
https://auth.azurewebsites.net/Account/Login?
ReturnUrl=%2Fconnect%2Fauthorize%2Fcallback%3F
client_id%3DLocal%26
redirect_uri%3Dhttp%253A%252F%252Flocalhost%253A4200%252Fauth-callback%252F%26
response_type%3Did_token%2520token%26
scope%3Dopenid%2520profile%2520Api%26
state%3D212ee56661074896aea2b6043d2b8a3f%26
nonce%3D393838b342d543d5910f38cbcab22fa0%26
loginType%3DInternal // my extra params
Issue 1 - state is undefined after callback
State is added to callback URL as below
http://localhost:4200/auth-callback#id_token=eyJhbG...
token_type=Bearer
&expires_in=300&
scope=openid%20profile%20Api&
state=155e3e4352814ca48e127547c134144e&
session_state=DPXW-ijMR4ST9iTSxgMwhsLq7aoknEZOnq3aFDooCFg.ifImJurwkwU6M5lwZXCUuw
State must be present in user. But in my case, I see the state as undefined in the callback method
async completeAuthentication() {
await this.manager
.signinRedirectCallback()
.then(x => {
this.user = x;
this.user.state = x.state; // undefined
this.user.session_state = x.session_state;
})
.catch(errorData => {
const expired = errorData;
});
Question --
- Where does oidc store state after generation?
- Why is state undefined? How to retrieve state after callback? I guess not by URL(path)!
- Does oidc internally validates state? How? Where?
Issue 2 - nonce
nonce value is received in id_token
created: 1594171097
extraTokenParams: {}
id: "5cc732d3b7fe4a0abdb371be3bda69a6"
nonce: "17c3f171328b4542a282fcbdd43d6fe4"
Also I see there are 2-4 oidc user are stored in local storage after login. why so? They have same user info but different ID and nonce. I user clearstalestate() to these all are generated after each fresh login or refresh
Questions -
- Why 2-4 user info is stored in local storage? which method generates the local storage user?
- The nonce value is per session or per user request?
- Where does the nonce value stored after generation?
- Does oidc validates nonce internally? Where? If not how should I do it?
So I have debugged the code and found the questions for your answers,
The nonce value is per session or per user request?
This should not be duplicated, so it is generated per request to mitigate the replay attacks
Where does the nonce value stored after generation?
Stored in session storage
Does oidc validates nonce internally? Where? If not how should I do it?
Yes it validates internally. You will have to look at the oidc-client js. I extracted some of code from there to get clear view,
}
Now coming back to state param validation. It is no longer available in User object, instead it is validated before hand internally. Here is the code extract for that from oidc-client js
Both, state and nonce are managed by oidc-client library.