Generic Oauth role_attribute_path jmespath failed to parse JSON

Hi everyone,

I’ve configured Oauth with role_attribute_path using the docs found here:


The basic example works as expected, if I map the role to a single field in the userinfo json. If I try to use a jamespath expression the parsing always fails with:

t=2020-04-25T15:16:27+0000 lvl=dbug msg=“Received user info response” logger=oauth.generic_oauth raw_json="{“sub”:“9f01d6ac-920e-442b-8bae-aa12e748732e”,“email_verified”:false,“user-roles”:[“offline_access”,“uma_authorization”],“name”:“Viewer Grafana”,“preferred_username”:“test-viewer”,“given_name”:“Viewer”,“family_name”:“Grafana”,“email”:“test-viewer@”}" data=“Name: Viewer Grafana, Displayname: , Login: , Username: , Email: test-viewer@, Upn: , Attributes: map[]”
t=2020-04-25T15:16:27+0000 lvl=eror msg=“Failed to search user info JSON response with provided path” logger=oauth.generic_oauth attributePath=“contains(user-roles[*], ‘monitoring’) && ‘Editor’ || ‘Viewer’” err=“SyntaxError: Invalid token: tNumber”

I’ve tried the expression and the json on jmespath dot org and the expression works, I’, also running the latest grafana version (6.7.3).

I think the issue is on this function:
pkg/login/social/generic_oauth.go
(…)
func (s *SocialGenericOAuth) searchJSONForAttr(attributePath string, data []byte) string

My config looks like this:

grafana.ini:
  server:
    root_url: <url>/grafana
  auth.anonymous:
    enabled: 'false'
  auth:
    disable_login_form: 'true'
    oauth_auto_login: 'true'
  auth.generic_oauth:
    enabled: true
    client_id: client-id
    auth_url: <url>/auth/realms/myrealm/protocol/openid-connect/auth
    token_url: <url>/auth/realms/myrealm/protocol/openid-connect/token
    api_url: <url>/auth/realms/myrealm/protocol/openid-connect/userinfo
    allowed_domains : <url>
    role_attribute_path: contains(user-roles[*], 'monitoring') && 'Editor' || 'Viewer'

  log.console:
    level: debug
  log:
    level: debug

(edited config to remove urls as I am only allowed 2 links)

Am I doing something wrong or is there an issue with the JamesPath search function?

Dash in the claim name is a problem for jmespath. You need to enclose it in quotes. Try:

role_attribute_path: contains('"user-roles[*]"', 'monitoring') && 'Editor' || 'Viewer'

CLI test:

$ echo '{"sub":"9f01d6ac-920e-442b-8bae-aa12e748732e","email_verified":false,"user-roles":["offline_access","uma_authorization"],"name":"Viewer Grafana","preferred_username":"test-viewer","given_name":"Viewer","family_name":"Grafana","email":"test-viewer@"}' | jp "contains('\"user-roles[*]\"', 'monitoring') && 'Editor' || 'Viewer'"
"Viewer"

Or you can customize claim name user-roles in your IdP (it looks like a Keycloak).

Thank you so much @jangaraj that is exactly what was missing.

I ended up with this expression that is working as I intend:
role_attribute_path: contains("user-roles"[*], 'monitoring') && 'Editor' || 'Viewer'