OIDC Provider sign certificate update impact on OIDC Clients
search cancel

OIDC Provider sign certificate update impact on OIDC Clients

book

Article ID: 277794

calendar_today

Updated On:

Products

SITEMINDER CA Single Sign On Federation (SiteMinder) CA Single Sign On Secure Proxy Server (SiteMinder)

Issue/Introduction


About the OIDC Provider certificates. When upgrading the signing and encryption certificate in OIDC Provider, how to share the certificate used to sign and encrypt with the OIDC Clients?

 

Resolution


About the tokens signature in OIDC, there's no need to share the signing certificate with the Resource Provider.

The Authorization Provider provides the kid and alg headers to the Resource Provider, and the Resource Provider gets the public key to validate a signature reaching the jwks endpoint at the Authorization Provider side.

Let's take a look at the a Resource Provider running on Apache. The Authorization Provider is CA Access Gateway (SPS) SiteMinder.

  Resource Provider:      wa.example.com
  Authorization Provider: sps.example.com

The Resource Provider gets the tokens from the Authorization Provider after authentication, which one gives the kid and alg headers (as per oidc module debug logs on Apache):

oidc_proto_parse_idtoken: successfully parsed (and possibly decrypted) JWT with header={"kid":"000 [...omitted for brevity...] 000","alg":"RS256"}, and payload={"sub":"cn=<user>,dc=example,dc=com","aud":"000 [...omitted for brevity...] 000","SessionToken":"Kpw [...omitted for brevity...] RYG","auth_time":1703759538,"givenName":"<user>","iss":"https://sps.example.com/affwebservices/CASSO/oidc/wa.example.com","exp":1703759838,"iat":1703759538,"nonce":"6zT [...omitted for brevity...] YMY","jti":"ODd [...omitted for brevity...] D0=","sid":"BHh [...omitted for brevity...] AI="}

The Resource Provider goes to the jwks endpoint to retrieve the public key (derived from the certificate) and validate the token signature:

oidc_metadata_jwks_get: enter, jwks_uri=https://sps.example.com/affwebservices/CASSO/oidc/jwks?AuthorizationProvider=sps.example.com, refresh=0
oidc_util_http_call: url=https://sps.example.com/affwebservices/CASSO/oidc/jwks?AuthorizationProvider=sps.example.com, data=(null), content_type=(null), basic_auth=null, bearer_token=(null), ssl_validate_server=0, timeout=60, outgoing_proxy=(null), pass_cookies=0, ssl_cert=(null), ssl_key=(null), ssl_key_pwd=(null)
oidc_util_http_call: HTTP response code=200
oidc_util_http_call: response={"keys":[{"kty":"RSA","e":"AQAB","use":"sig","kid":"000 [...omitted for brevity...] 000","n":"qVx [...omitted for brevity...] c4M"}]}

The Resource Provider stores in its cache the public key:

oidc_cache_set: successfully stored 270 bytes in shm cache backend for key https://sps.example.com/affwebservices/CASSO/oidc/jwks?AuthorizationProvider=sps.example.com

Then the Resource Provider validates the signature with the public key it received:

oidc_proto_get_key_from_jwks: found matching kid: "000 [...omitted for brevity...] 000" for jwk: {"kty":"RSA","kid":"000 [...omitted for brevity...] 000","e":"<value>","n":"qVx [...omitted for brevity...] c4M"}
oidc_proto_get_keys_from_jwks_uri: returning 1 key(s) obtained from the (possibly cached) JWKs URI
oidc_proto_jwt_verify: JWT signature verification with algorithm "RS256" was successful
oidc_proto_validate_idtoken: enter, jwt.header="{"kid":"000 [...omitted for brevity...] 000","alg":"RS256"}", jwt.payload="{"sub":"cn=<user>,dc=example,dc=com","aud":"000 [...omitted for brevity...] 000","SessionToken":"Kpw [...omitted for brevity...] RYG","auth_time":1703759538,"givenName":"<user>","iss":"https://sps.example.com/affwebservices/CASSO/oidc/wa.example.com","exp":1703759838,"iat":1703759538,"nonce":"6zT [...omitted for brevity...] Kck_Sw5xTHBYMY","jti":"ODdiYmFlNGMtNTYwNi00MGFjLTk4MjQtMmYyYTkwMDE5ZjdkLTQvcUpDMmRCQ0ZRNExCa2hFTVBSSlFXKzVpND0=","sid":"BHh [...omitted for brevity...] hAI="}", nonce="6zT [...omitted for brevity...] YMY"
oidc_cache_get: enter: 6zT [...omitted for brevity...] YMY (section=n, decrypt=0, type=shm)
oidc_cache_get: cache miss from shm cache backend for key 6zT [...omitted for brevity...] YMY
oidc_cache_set: enter: 6zT [...omitted for brevity...] YMY (section=n, len=43, encrypt=0, ttl(s)=1210, type=shm)
oidc_cache_set: successfully stored 43 bytes in shm cache backend for key 6zT [...omitted for brevity...] YMY
oidc_proto_validate_nonce: nonce "6zT [...omitted for brevity...] YMY" validated successfully and is now cached for 1210 seconds