curityio / flask-of-oil

An OAuth 2.0 filter written in Python to protect APIs built using Flask
https://curity.io/resources/learn/oauth-filter-for-python-flask/
Apache License 2.0
19 stars 11 forks source link

Relax 'sub' claim requirement #18

Open mattmshell opened 1 year ago

mattmshell commented 1 year ago

Thank you for this well designed and rational library. My IdP setup, PingID + Azure AD, issues access_tokens with the 'sub' claim. For example, I receive:

{
  "scope": [
    "openid",
    "email",
    "profile",
    "offline_access"
  ],
  "client_id": "my-client-id",
  "iss": "https://my-idp.domain.com",
  "aud": "my-idp.domain.com",
  "uid": "myupn",
  "mail": "mattmshell@example.com",
  "givenName": "Matt",
  "sn": "Mshell",
  "exp": 1669109174
}

This results in the following failure to auth:

# jwt_validatory.py L113
if 'sub' not in payload:
    self.logger.debug("No subject in body, invalid token")
    return {"active": False}

The specs on this claim are at odds with one another.

RFC 7519

The “sub” (subject) claim identifies the principal that is the subject of the JWT. The claims in a JWT are normally statements about the subject. The subject value MUST either be scoped to be locally unique in the context of the issuer or be globally unique. The processing of this claim is generally application specific. The “sub” value is a case-sensitive string containing a StringOrURI value. Use of this claim is OPTIONAL.

OpenID Connect Core 1.0

REQUIRED. Subject Identifier. A locally unique and never reassigned identifier within the Issuer for the End-User, which is intended to be consumed by the Client, e.g., 24400320or AItOawmwtWwcT0k51BayewNvutrJUqsvl6qs7A4. It MUST NOT exceed 255 ASCII characters in length. The sub value is a case sensitive string.

Can this check be relaxed, or possibly the check made conditional via configuration?

mtrojanowski commented 1 year ago

Hi Matt, thanks for the comment.

It's true that we could relax the requirement and make the verification configurable. I will try to add such a feature shortly.

The two specifications that you quote are actually not at odds. The OIDC core spec defines the ID token, and there the sub claim is required. In other JWTs, as defined in RFC 7519, sub is not a required claim (e.g. JWT access tokens do not have to use that claim).