mozilla / mozilla-django-oidc

A django OpenID Connect library
https://mozilla-django-oidc.readthedocs.io
Mozilla Public License 2.0
452 stars 169 forks source link

Enabling ES256/384/512 #442

Closed ftang001 closed 10 months ago

ftang001 commented 3 years ago

I have been working with a provider that prefers ES256, so did some quick tests to see how hard it would be to extend support in mozilla-django-oidc. As the flow is similar to RS*** and it's supported by josepy, it turns out to be very easy indeed - just 2 lines in auth.py and it seems to work:

*** old.auth.py Fri Oct 29 15:34:42 2021
--- new.auth.py Fri Oct 29 15:39:54 2021
***************
*** 53,59 ****
          self.OIDC_RP_SIGN_ALGO = self.get_settings('OIDC_RP_SIGN_ALGO', 'HS256')
          self.OIDC_RP_IDP_SIGN_KEY = self.get_settings('OIDC_RP_IDP_SIGN_KEY', None)

!         if (self.OIDC_RP_SIGN_ALGO.startswith('RS') and
                  (self.OIDC_RP_IDP_SIGN_KEY is None and self.OIDC_OP_JWKS_ENDPOINT is None)):
              msg = '{} alg requires OIDC_RP_IDP_SIGN_KEY or OIDC_OP_JWKS_ENDPOINT to be configured.'
              raise ImproperlyConfigured(msg.format(self.OIDC_RP_SIGN_ALGO))
--- 53,59 ----
          self.OIDC_RP_SIGN_ALGO = self.get_settings('OIDC_RP_SIGN_ALGO', 'HS256')
          self.OIDC_RP_IDP_SIGN_KEY = self.get_settings('OIDC_RP_IDP_SIGN_KEY', None)

!         if ((self.OIDC_RP_SIGN_ALGO.startswith('RS') or self.OIDC_RP_SIGN_ALGO.startswith('ES')) and
                  (self.OIDC_RP_IDP_SIGN_KEY is None and self.OIDC_OP_JWKS_ENDPOINT is None)):
              msg = '{} alg requires OIDC_RP_IDP_SIGN_KEY or OIDC_OP_JWKS_ENDPOINT to be configured.'
              raise ImproperlyConfigured(msg.format(self.OIDC_RP_SIGN_ALGO))
***************
*** 185,191 ****
          nonce = kwargs.get('nonce')

          token = force_bytes(token)
!         if self.OIDC_RP_SIGN_ALGO.startswith('RS'):
              if self.OIDC_RP_IDP_SIGN_KEY is not None:
                  key = self.OIDC_RP_IDP_SIGN_KEY
              else:
--- 185,191 ----
          nonce = kwargs.get('nonce')

          token = force_bytes(token)
!         if self.OIDC_RP_SIGN_ALGO.startswith('RS') or self.OIDC_RP_SIGN_ALGO.startswith('ES'):
              if self.OIDC_RP_IDP_SIGN_KEY is not None:
                  key = self.OIDC_RP_IDP_SIGN_KEY
              else:

Is anyone keen to review / add this?

Thanks.

themooer1 commented 2 years ago

Were you able to get this same thing working with P256? I tried adding self.OIDC_RP_SIGN_ALGO.startswith('PS') in those same places, but josepy refused to verify the signatures even though the RSA keys stayed the same.

josepy did successfully parse the RSA signing key from the JWKS endpoint, and recognized that the signature was PS256.

akatsoulas commented 10 months ago

Fixed in v4.0.0