IdentityModel / IdentityModel.OidcClient.Samples

Apache License 2.0
292 stars 162 forks source link

Invalid Grant error when deployed to Production #116

Open fraserbooth opened 3 years ago

fraserbooth commented 3 years ago

First a big thank you to @leastprivilege for all your amazing work :)

I've inherited a solution that uses Identity Server 4 and is working well. While experimenting with this sample it works fine against localhost, but when trying to connect the Client to Production I'm getting:

'Invalid grant type for client: "authorization_code"'

I've been exploring the issue on StackOverflow: https://stackoverflow.com/questions/69183994/identity-server4-gives-invalid-grant-error-when-deployed-to-production-but-wo?noredirect=1#comment122318014_69183994

...and the conclusion seems to be that in Production the Client also needs HTTPS. I suppose you have used this sample in Production against an SSL Secured Identity Server 4. Did you have any issues?

When changing the RedirectUri to HTTPS I get:

'HTTPS endpoints can only be configured using KestrelServerOptions.Listen().'

...and am now stuck in various loops trying to work out how to configure Kestrel and get Certificates onto Client machines to integrate into my solution. Just wanting to make sure I'm barking up the right tree and see if there is an easier way :)

Further reading of closed issue #89: ...in this Repo suggests that http loopback should still be fine in Production: https://tools.ietf.org/html/rfc8252#section-7 ...so I'm at loose end where I've gone wrong.

leastprivilege commented 3 years ago

You need to check the server logs why you are getting the invalid_grant. I am sure it is a config problem.

fraserbooth commented 3 years ago

Thank you for you reply :)

The server logs show the following:

Start authorize request
No user present in authorize request
Start authorize request protocol validation
desktopClient found in database: True
client configuration validation for client "desktopClient" succeeded.
Checking for PKCE parameters
AuthorizeRequestValidationLog { ClientId: "desktopClient", ClientName: "Desktop", RedirectUri: "http://127.0.0.1:53508", AllowedRedirectUris: ["http://127.0.0.1:53508"], SubjectId: "anonymous", ResponseType: "code", ResponseMode: "query", GrantType: "authorization_code", RequestedScopes: "", State: "850ea39012d6cb9957943eec7e0d4940", UiLocales: null, Nonce: null, AuthenticationContextReferenceClasses: null, DisplayMode: null, PromptMode: null, MaxAge: null, LoginHint: null, SessionId: null, Raw: [("response_type": "code"), ("nonce": "cb71ec9cf7cd6ae6d4cad312f0a19769"), ("state": "850ea39012d6cb9957943eec7e0d4940"), ("code_challenge": "n-UyLEqkbUKjBFzP5-QQYjb5_l1G95pmtt6D_sqWUxE"), ("code_challenge_method": "S256"), ("client_id": "desktopClient"), ("scope": "openid profile api offline_access"), ("redirect_uri": "http://127.0.0.1:53508")] }
Invalid grant type for client: "authorization_code"
Request validation failed
AuthorizeRequestValidationLog { ClientId: "desktopClient", ClientName: "Desktop", RedirectUri: "http://127.0.0.1:53508", AllowedRedirectUris: ["http://127.0.0.1:53508"], SubjectId: "anonymous", ResponseType: "code", ResponseMode: "query", GrantType: "authorization_code", RequestedScopes: "", State: "850ea39012d6cb9957943eec7e0d4940", UiLocales: null, Nonce: null, AuthenticationContextReferenceClasses: null, DisplayMode: null, PromptMode: null, MaxAge: null, LoginHint: null, SessionId: null, Raw: [("response_type": "code"), ("nonce": "cb71ec9cf7cd6ae6d4cad312f0a19769"), ("state": "850ea39012d6cb9957943eec7e0d4940"), ("code_challenge": "n-UyLEqkbUKjBFzP5-QQYjb5_l1G95pmtt6D_sqWUxE"), ("code_challenge_method": "S256"), ("client_id": "desktopClient"), ("scope": "openid profile api offline_access"), ("redirect_uri": "http://127.0.0.1:53508")] }
TokenIssuedFailureEvent { ClientId: "desktopClient", ClientName: "Desktop", RedirectUri: "http://127.0.0.1:53508", Endpoint: "Authorize", SubjectId: null, Scopes: "", GrantType: "authorization_code", Error: "unauthorized_client", ErrorDescription: "Invalid grant type for client", Category: "Token", Name: "Token Issued Failure", EventType: Failure, Id: 2001, Message: null, ActivityId: "80004ac4-0000-ef00-b63f-84710c7967bb", TimeStamp: 09/12/2021 17:53:13, ProcessId: 20916, LocalIpAddress: "10.0.0.4:443", RemoteIpAddress: "195.206.180.132" }
Request finished in 810.6797ms 302 

The Production config is working fine for my ReactJS Web App using the implicit Grant Type, but my understand is authorization_code is better for a Desktop App with Refresh Tokens etc.

My confusion is that I have the same configuration for the authorization_code on my local development environment which is working fine. I am not sure how to work out what config changes are needed between Local and Production.

leastprivilege commented 3 years ago

What's the allowed grant types for the client in production?

fraserbooth commented 3 years ago

In both Local & Production the Desktop Client is given GrantType "authorization_code" in the ClientGrantTypes table in SQL, however in Production its throwing this "Invalid grant type for client: "authorization_code"" error.