Hi all,
Currently, when configuring external identity providers in WSO2 Identity
Server, relevant X.509 public certificate of the Identity provider needs to
be uploaded for signature verification purposes. However, we can also
provide the keys of the identity provider in jwks_uri format [1]. JWKs uri
represents the cryptographic keys used by the Identity provider for signing
RS256 tokens. We need to have a way to support JWKS based validation for
signatures [2].
The main benefit of allowing JWKS endpoint configuration is the ability to
handle key rotation by external identity providers. Configuring this
endpoint would enable us to programmatically discover JSON web keys and
allow the third party identity providers to publish new keys without having
the overhead of notifying each and every client application. This will
allow painless key rollover and integration.
Please find the following task break down for this feature.
- Add ability to configure jwks_uri in identity providers.
- Implement jwks_uri based certificate/key loading.
- Add ability to refresh certificate/keys if key rotation is enabled at
the identity provider side.
- Update identity provider certificate usage based implementations.
*Add ability to configure jwks_uri in identity-providers*
In order to provide the ability to configure jwks_uri , we can configure an
additional configuration property under IDP configuration section. We can
add the jwks_uri as an additional IDP property and it will be persisted in
IDP_METADATA as a name-value pair against the IDP id. Following improvement
will be made to IDP configuration UI.
One of the concerns here is that, since we allow the user to configure both
jwks_uri and public certificate from IDP configuration, in a scenario where
both are configured we should prioritize the jwks_uri based certificate
validation over the uploaded one.
*Implement the jwks_uri based key loading and refresh *For this, we have
the following options.
1. Obtain the public key used to sign the tokens and assertions from
JWKS endpoint manually and verify the token signatures. Here the major
requirement would be to cache the JWKS locally to save the network round
trip time since a cache storage is generally more efficient than a DB one.
However the cache needs to be updated with key rollover at the remote
server. As a solution we can use following options,
- configure a key refresh period in IDP configuration, to periodically
refresh the keys and update cache.
- Verify the Key identifier parameter (kid) of the JWT [3] and
against the kid of the cached key set. If it fails to recognize the kid,
retrieve the new public key set from the jwks_uri endpoint [4].
2. Use a third party library which has inbuilt capabilities for
handling JWKS based JWT verification with the option to cache.
IMO, the effective approach would be to rely on an existing library that
provide the inbuilt functionalities to handle JWKS based JWT validation
along with caching mechanisms.
*Use a third party library which has inbuilt JWKS capabilities *Following
are some of the available libraries with jwt/jwks capabilities.
- https://bitbucket.org/connect2id/nimbus-jose-jwt
- https://github.com/auth0/jwks-rsa-java
>From above libraries the best approach would be to proceed with
nimbus-jose-jwt due to the following reasons.
- nimbus-jose-jwt is already used for signature verification with our
current implementations [5].
- With nimbus-jose-jwt we can simply pass the JWT to the inbuilt
verify() function which will handle JWT signature validation.
- For other assertion verification we can construct the RSAPublicKey
from JWKS parameters.
- With RemoteJWKSet [6], we can retrieve the JWKS from a remote endpoint
and the retrieved JWK set can be configured to cache in order to to
minimize network calls. Therefore, it will speed up subsequent look-ups.
- This is also capable of handling key rotation at the remote server
since the cache is updated whenever the key selector tries to get a key
with an unknown ID.
*Update identity provider certificate usage based implementations*This
feature will be developed as a common OSGi service that can be used by any
other component for JWKS based token validations. E.g SAML bearer grant,
JWT grant
Appreciate your suggestions and concerns over the suggested approach.
[1]
http://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
[2]
https://auth0.com/docs/jwks#using-the-jwks-in-your-application-to-verify-a-jwt
[3] https://tools.ietf.org/html/rfc7517#section-4.5
[4]
https://docops.ca.com/ca-api-management-oauth-toolkit/4-2/en/openid-connect-implementation/retrieve-the-json-web-key-set-jwks
[5]
https://github.com/wso2-extensions/identity-oauth2-grant-jwt/blob/master/component/grant-type/src/main/java/org/wso2/carbon/identity/oauth2/grant/jwt/JWTBearerGrantHandler.java
[6]
https://static.javadoc.io/com.nimbusds/nimbus-jose-jwt/5.4/com/nimbusds/jose/jwk/source/RemoteJWKSet.html
Thanks,
Sathya
--
Sathya Bandara
Software Engineer
WSO2 Inc. http://wso2.com
Mobile: (+94) 715 360 421 <+94%2071%20411%205032>
_______________________________________________
Architecture mailing list
[email protected]
https://mail.wso2.org/cgi-bin/mailman/listinfo/architecture