XenitAB/go-oidc-middleware

withRequiredClaims doesn't support its function signature

idc77 opened this issue ยท 13 comments

idc77 commented

a JWT with the following body:

  "iat": 1635250590,
  "auth_time": 1635250589,
  "jti": "e7f11506-04b5-470a-b546-5365bea7dc74",
  "iss": "https://redacted/auth/realms/redacted",
  "aud": [
    "devel",
    "account"
  ],
  "sub": "4d1debda-2a29-4caf-9b7f-a8474051f6b6",
  "typ": "Bearer",
  "azp": "devel",
  "nonce": "ec137176-9c23-4375-849e-74bb20c7fbea",
  "session_state": "5618efe5-2bcf-4c35-8730-ae17b8258404",
  "acr": "1",
  "allowed-origins": [
    "*"
  ],
  "realm_access": {
    "roles": [
      "offline_access",
      "default-roles-redacted",
      "uma_authorization",
      "user"
    ]
  },
  "resource_access": {
    "account": {
      "roles": [
        "manage-account",
        "manage-account-links",
        "view-profile"
      ]
    }
  },
  "scope": "openid email profile",
  "sid": "5618efe5-2bcf-4c35-8730-ae17b8258404",
  "email_verified": true,
  "name": "redacted",
  "preferred_username": "redacted",
  "given_name": "redacted",
  "family_name": "redacted",
  "email": "redacted"
}

and gin (fwiw) middleware the following options:

	oidcHandler := oidcgin.New(
		options.WithIssuer(cfg.Issuer),
		options.WithRequiredTokenType("JWT"),
		options.WithRequiredAudience(cfg.Audience),
		options.WithRequiredClaims(map[string]interface{}{
			"realm_access": map[string]interface{}{
				"roles": "user",
			},
		}),
	)

and the default handler

func OIDCHandler(cx *gin.Context) {
	claimsValue, found := cx.Get("claims")
	if !found {
		fmt.Println("!found")
		cx.AbortWithStatus(http.StatusUnauthorized)
		return
	}

	claims, ok := claimsValue.(map[string]interface{})
	if !ok {
		fmt.Println("!ok")
		cx.AbortWithStatus(http.StatusUnauthorized)
		return
	}

	cx.JSON(http.StatusOK, claims)
}

results in the following error message

Error #01: unable to validate required claims: unable to get cty.Type: no cty.Type for interface {}
idc77 commented

this

	oidcHandler := oidcgin.New(
		options.WithIssuer(cfg.Issuer),
		options.WithRequiredTokenType("JWT"),
		options.WithRequiredAudience(cfg.Audience),
		options.WithRequiredClaims(map[string]interface{}{
			"roles": "user",
		}),
	)

also doesn't work

Error #01: unable to validate required claims: unable to get cty.Type: no cty.Type for interface {}

What is the correct way to pass arguments to options.WithRequiredClaims ?

Hi!

This may be something I haven't thought about and I may have to implement logic for it.

Can you please try the following and see if it works?

	oidcHandler := oidcgin.New(
		options.WithIssuer(cfg.Issuer),
		options.WithRequiredTokenType("JWT"),
		options.WithRequiredAudience(cfg.Audience),
		options.WithRequiredClaims(map[string]interface{}{
		        "foo": []string{"bar"},
	        }),
	)
idc77 commented

Hello,

this works, yes

@idc77 ah, great! ๐Ÿ‘

@idc77 did you try with your specific values instead of foo?

idc77 commented

no because it doesn't fit the use case, see the inital post.
"realm_access.roles" = "user"

Ah, I'll build a test around this and check ๐Ÿ‘ I'll get back to you here when I've had some time to look at it, but may take a few days.

idc77 commented

alright, no worries, it's not urgent :) thanks

idc77 commented

I've been thinking, maybe allow passing of structs

like

	type ClaimCheckObject struct {
		RealmAccess struct{
			Roles []string `json:"roles" cty:"roles"`
		} `json:"realm_access" cty:"realm_access"`
	}

Good catch @idc77! This was a bug. ๐Ÿฅ‡

My solution is to infer the type of the received claims based on the configured required claims. If all the CI goes through, I'll merge and do a release.

When #84 is released, you should be able to get it by doing the following:

options.WithRequiredClaims(map[string]interface{}{
	"realm_access": map[string][]string{
		"roles": {"user"},
	}
})

Please try it out and report back if it's working for you as expected.

v0.0.17 is now released

idc77 commented

Feedback: I tried it and there are no issues. Thank you.

@idc77 great! No problem ๐Ÿ˜Š