IdentityModel / oidc-client-js

OpenID Connect (OIDC) and OAuth2 protocol support for browser-based JavaScript applications
Apache License 2.0
2.43k stars 841 forks source link

Auth Code flow broken but Implicit works fine #1226

Closed cwoolum closed 4 years ago

cwoolum commented 4 years ago

I've been trying to dig through this issue all day and am not quite sure where the problem lies. I have an app that was working fine using implicit flow. I've changed the response type to code but now I get a 401 when trying to exchange the code for an id token. I've been trying to debug through the full sign in flow and from what I can tell, the state is removed from the store at line 116 during the callback and then it is unable to use that state to exchange the code for an id token.

https://github.com/IdentityModel/oidc-client-js/blob/f62cfa72e36465776c0fdb13ae6253d238ad5eff/src/OidcClient.js#L116-L126

Here is a copy of my logs:

WebStorageStateStore.get user:https://idp.myid-stg.redacted.com:cookie-sharing-poc
redux-logger.js?d665:1  action @@router/LOCATION_CHANGE @ 17:31:32.111
oidc-client.min.js?dd17:1 OidcClient.processSigninResponse
oidc-client.min.js?dd17:1 OidcClient.readSigninResponseState
oidc-client.min.js?dd17:1 WebStorageStateStore.remove 6a0593f92ccd4a349a1916cddf45fde3   #State is removed
oidc-client.min.js?dd17:1 UserManager._loadUser: no user storageString   #State not found
oidc-client.min.js?dd17:1 SigninState.fromStorageString
oidc-client.min.js?dd17:1 UserManager.getUser: user not found in storage
oidc-client.min.js?dd17:1 OidcClient.processSigninResponse: Received state from storage; validating response
oidc-client.min.js?dd17:1 ResponseValidator.validateSigninResponse
oidc-client.min.js?dd17:1 ResponseValidator._processSigninParams: state validated
redux-logger.js?d665:1  action redux-oidc/USER_EXPIRED @ 17:31:58.917
redux-logger.js?d665:1  action redux-oidc/USER_EXPIRED @ 17:31:58.920
oidc-client.min.js?dd17:1 ResponseValidator.validateSigninResponse: state processed
oidc-client.min.js?dd17:1 ResponseValidator._validateTokens: Validating code
oidc-client.min.js?dd17:1 MetadataService.getMetadataProperty for: token_endpoint
oidc-client.min.js?dd17:1 MetadataService.getMetadata: getting metadata from https://idp.myid-stg.redacted.com/.well-known/openid-configuration
oidc-client.min.js?dd17:1 JsonService.getJson, url:  https://idp.myid-stg.redacted.com/.well-known/openid-configuration
oidc-client.min.js?dd17:1 JsonService.getJson: HTTP response received, status 200
oidc-client.min.js?dd17:1 MetadataService.getMetadata: json received
oidc-client.min.js?dd17:1 MetadataService.getMetadataProperty: metadata recieved
oidc-client.min.js?dd17:1 TokenClient.exchangeCode: Received token endpoint
oidc-client.min.js?dd17:1 JsonService.postForm, url:  https://idp.myid-stg.redacted.com/as/token.oauth2
oidc-client.min.js?dd17:1 POST https://idp.myid-stg.redacted.com/as/token.oauth2 401

oidc-client.min.js?dd17:1 JsonService.postForm: HTTP response received, status 401

Since it can't find the existing state anymore, it seems to create a new one to send with the authorization_code request and the code_verifier then does not match. Is there something I'm missing here?

My config is as follows:

response_type: 'code',
scope: 'openid profile id.uuid id email'
brockallen commented 4 years ago

Last time I ran the code, code flow w/ PKCE is working fine. So not sure. Check the server logs as to why it returns 401. Perhaps the lack of a client secret?

cwoolum commented 4 years ago

It turns out that not having the client secret was the problem. Our IDP doesn't support auth code flow without it.