[error] login.OAuthLogin(state mismatch)

Having an issue with generic_oauth authentication method.

  • running one instance of grafana 6.2.0 on centOS droplet.
  • protocol: https with no reverse proxy in front
  • main database is postgres
  • remote cache default setting

Relevant settings below:

enforce_domain = true
cookie_secure = true
cookie_samesite = none

[auth.generic_oauth]
enabled = true
name = GenericOauth
allow_sign_up = true
client_id = secret
client_secret = secret
scopes = openid email
auth_url = https://sso.provider.com/provider/oidc/endpoint/oidcidp/authorize
token_url = https://sso.provider.com/provider/oidc/endpoint/oidcidp/token
api_url =
send_client_credentials_via_post = true

Log entry for login attempt:

t=2019-07-05T07:22:51+0000 lvl=info msg="Request Completed" logger=context userId=0 orgId=0 uname= method=GET path=/ status=302 remote_addr=10.10.10.10 time_ms=0 size=29 referer=
t=2019-07-05T07:22:54+0000 lvl=info msg="Request Completed" logger=context userId=0 orgId=0 uname= method=GET path=/login/generic_oauth status=302 remote_addr=10.10.10.10 time_ms=0 size=336 referer=https://mywebsite.cf:3000/login
t=2019-07-05T07:22:57+0000 lvl=dbug msg="Scheduling update" logger=alerting.scheduler ruleCount=0
t=2019-07-05T07:23:07+0000 lvl=dbug msg="Scheduling update" logger=alerting.scheduler ruleCount=0
t=2019-07-05T07:23:13+0000 lvl=info msg="state check" logger=oauth queryState=7d4715445d76ac210d3ead75ec8b3ea2049047f51637f41553241230675e2470 cookieState=1856c8ee017fcef457d1b4bcd457d6f316ca94a21e69891a29d46cfcd271e7cf
t=2019-07-05T07:23:13+0000 lvl=eror msg="Request Completed" logger=context userId=0 orgId=0 uname= method=GET path=/login/generic_oauth status=500 remote_addr=10.10.10.10 time_ms=0 size=1737 referer="https://sso.provider.com/provider/oidc/endpoint/oidcidp/authorize?access_type=online&client_id=ZjE3ZGQ5ZGMtYmE0ZS00&redirect_uri=https://mywebsite.cf:3000/login/generic_oauth&response_type=code&scope=openid%20email&state=1chnbcpOD4JUNefvUsSQxPIn9xRnMEXD680b0IjBXNs="
t=2019-07-05T07:23:14+0000 lvl=info msg="Request Completed" logger=context userId=0 orgId=0 uname= method=GET path=/login/public/img/fav32.png status=404 remote_addr=10.10.10.10 time_ms=249 size=22825 referer=
t=2019-07-05T07:23:14+0000 lvl=info msg="Request Completed" logger=context userId=0 orgId=0 uname= method=GET path=/favicon.ico status=404 remote_addr=10.10.10.10 time_ms=250 size=22825 referer=

In the log entry the cookieState and the queryState are different but i cannot figure out why that is.

The state in the URL string is the same from start to finish (sans the mishandling in enconding)


7j6_ZCI-h7KGMkzN0qt7DTyVvUo6A05cAJrEHW8JnFA%3D
7j6_ZCI-h7KGMkzN0qt7DTyVvUo6A05cAJrEHW8JnFA=
7j6_ZCI-h7KGMkzN0qt7DTyVvUo6A05cAJrEHW8JnFA%253D 

https://sso.provider/provider/oidc/endpoint/oidcidp/authorize?access_type=online&client_id=ZjE3ZGQ5ZGMtYmE0ZS00&redirect_uri=https%3A%2F%2Fmywebsite.cf%3A3000%2Flogin%2Fgeneric_oauth&response_type=code&scope=openid+email&state=7j6_ZCI-h7KGMkzN0qt7DTyVvUo6A05cAJrEHW8JnFA%3D

https://sso.provider/provider/oidc/endpoint/oidcidp/authorize?access_type=online&client_id=ZjE3ZGQ5ZGMtYmE0ZS00&redirect_uri=https://mywebsite.cf:3000/login/generic_oauth&response_type=code&scope=openid%20email&state=7j6_ZCI-h7KGMkzN0qt7DTyVvUo6A05cAJrEHW8JnFA=

https://mywebsite.cf:3000/login/generic_oauth?code=SxqbDiBbD7LPRXsYX1XjFkscdPZOfK&state=7j6_ZCI-h7KGMkzN0qt7DTyVvUo6A05cAJrEHW8JnFA%253D

I’ve been wrapping my head around this for a week now with no luck.

1 Like

The problem is that % is double escaped in the url returned from the provider.

It should be:
https://mywebsite.cf:3000/login/generic_oauth?code=SxqbDiBbD7LPRXsYX1XjFkscdPZOfK& state=7j6_ZCI-h7KGMkzN0qt7DTyVvUo6A05cAJrEHW8JnFA%3D

instead of:
https://mywebsite.cf:3000/login/generic_oauth?code=SxqbDiBbD7LPRXsYX1XjFkscdPZOfK& state=7j6_ZCI-h7KGMkzN0qt7DTyVvUo6A05cAJrEHW8JnFA%253D

In the first case the unescaped state will be:
7j6_ZCI-h7KGMkzN0qt7DTyVvUo6A05cAJrEHW8JnFA= and in the latter:
7j6_ZCI-h7KGMkzN0qt7DTyVvUo6A05cAJrEHW8JnFA%3D
which have different hashes.

I have decoded the state but no change, same error. Plus, isn’t that decoded automatically anyway?

That looks like faulty IdP or misconfiguration on the IDP side (e. g. misconfigured nginx in front of IDP).