@@ -223,7 +223,8 @@ char *oidc_response_make_sid_iss_unique(request_rec *r, const char *sid, const c
223223 */
224224apr_byte_t oidc_response_save_in_session (request_rec * r , oidc_cfg_t * c , oidc_session_t * session ,
225225 oidc_provider_t * provider , const char * remoteUser , const char * id_token ,
226- oidc_jwt_t * id_token_jwt , const char * claims , const char * access_token ,
226+ oidc_jwt_t * id_token_jwt , const char * s_userinfo_claims ,
227+ json_t * userinfo_claims , const char * access_token ,
227228 const char * access_token_type , const int expires_in , const char * refresh_token ,
228229 const char * scope , const char * session_state , const char * state ,
229230 const char * original_url , const char * userinfo_jwt ) {
@@ -235,7 +236,7 @@ apr_byte_t oidc_response_save_in_session(request_rec *r, oidc_cfg_t *c, oidc_ses
235236 session -> expiry = apr_time_now () + apr_time_from_sec (oidc_cfg_session_inactivity_timeout_get (c ));
236237
237238 /* store the claims payload in the id_token for later reference */
238- oidc_session_set_idtoken_claims (r , session , id_token_jwt -> payload .value .str );
239+ oidc_session_set_idtoken_claims (r , session , id_token_jwt -> payload .value .json );
239240
240241 if (oidc_cfg_store_id_token_get (c )) {
241242 /* store the compact serialized representation of the id_token for later reference */
@@ -272,7 +273,7 @@ apr_byte_t oidc_response_save_in_session(request_rec *r, oidc_cfg_t *c, oidc_ses
272273 oidc_cfg_provider_userinfo_refresh_interval_get (provider ));
273274
274275 /* store claims resolved from userinfo endpoint */
275- oidc_userinfo_store_claims (r , c , session , provider , claims , userinfo_jwt );
276+ oidc_userinfo_store_claims (r , c , session , provider , userinfo_claims , userinfo_jwt );
276277
277278 /* see if we have an access_token */
278279 if (access_token != NULL ) {
@@ -485,7 +486,7 @@ static apr_byte_t oidc_response_flows(request_rec *r, oidc_cfg_t *c, oidc_proto_
485486 * set the unique user identifier that will be propagated in the Apache r->user and REMOTE_USER variables
486487 */
487488static apr_byte_t oidc_response_set_request_user (request_rec * r , oidc_cfg_t * c , oidc_provider_t * provider ,
488- oidc_jwt_t * jwt , const char * s_claims ) {
489+ oidc_jwt_t * jwt , json_t * userinfo_claims ) {
489490
490491 const char * issuer = oidc_cfg_provider_issuer_get (provider );
491492 char * claim_name = apr_pstrdup (r -> pool , oidc_cfg_remote_user_claim_name_get (c ));
@@ -501,13 +502,12 @@ static apr_byte_t oidc_response_set_request_user(request_rec *r, oidc_cfg_t *c,
501502 /* extract the username claim (default: "sub") from the id_token payload or user claims */
502503 apr_byte_t rc = FALSE;
503504 char * remote_user = NULL ;
504- json_t * claims = NULL ;
505- oidc_util_json_decode_object (r , s_claims , & claims );
506- if (claims == NULL ) {
505+ if (userinfo_claims == NULL ) {
507506 rc = oidc_get_remote_user (r , claim_name , oidc_cfg_remote_user_claim_get (c )-> reg_exp ,
508507 oidc_cfg_remote_user_claim_get (c )-> replace , jwt -> payload .value .json ,
509508 & remote_user );
510509 } else {
510+ json_t * claims = json_copy (userinfo_claims );
511511 oidc_util_json_merge (r , jwt -> payload .value .json , claims );
512512 rc = oidc_get_remote_user (r , claim_name , oidc_cfg_remote_user_claim_get (c )-> reg_exp ,
513513 oidc_cfg_remote_user_claim_get (c )-> replace , claims , & remote_user );
@@ -550,7 +550,7 @@ static int oidc_response_process(request_rec *r, oidc_cfg_t *c, oidc_session_t *
550550
551551 oidc_provider_t * provider = NULL ;
552552 oidc_proto_state_t * proto_state = NULL ;
553- oidc_jwt_t * jwt = NULL ;
553+ oidc_jwt_t * id_token = NULL ;
554554
555555 /* see if this response came from a browser-back event */
556556 if (oidc_response_browser_back (r , apr_table_get (params , OIDC_PROTO_STATE ), session ) == TRUE)
@@ -593,12 +593,12 @@ static int oidc_response_process(request_rec *r, oidc_cfg_t *c, oidc_session_t *
593593 }
594594
595595 /* handle the code, implicit or hybrid flow */
596- if (oidc_response_flows (r , c , proto_state , provider , params , response_mode , & jwt ) == FALSE) {
596+ if (oidc_response_flows (r , c , proto_state , provider , params , response_mode , & id_token ) == FALSE) {
597597 OIDC_METRICS_COUNTER_INC (r , c , OM_AUTHN_RESPONSE_ERROR_PROTOCOL );
598598 return oidc_response_authorization_error (r , c , proto_state , "Error in handling response type." , NULL );
599599 }
600600
601- if (jwt == NULL ) {
601+ if (id_token == NULL ) {
602602 oidc_error (r , "no id_token was provided" );
603603 return oidc_response_authorization_error (r , c , proto_state , "No id_token was provided." , NULL );
604604 }
@@ -610,9 +610,10 @@ static int oidc_response_process(request_rec *r, oidc_cfg_t *c, oidc_session_t *
610610 * optionally resolve additional claims against the userinfo endpoint
611611 * parsed claims are not actually used here but need to be parsed anyway for error checking purposes
612612 */
613- const char * claims = oidc_userinfo_retrieve_claims (
613+ json_t * userinfo_claims = NULL ;
614+ const char * s_userinfo_claims = oidc_userinfo_retrieve_claims (
614615 r , c , provider , apr_table_get (params , OIDC_PROTO_ACCESS_TOKEN ),
615- apr_table_get (params , OIDC_PROTO_TOKEN_TYPE ), NULL , jwt -> payload .sub , & userinfo_jwt );
616+ apr_table_get (params , OIDC_PROTO_TOKEN_TYPE ), NULL , id_token -> payload .sub , & userinfo_claims , & userinfo_jwt );
616617
617618 /* restore the original protected URL that the user was trying to access */
618619 const char * original_url = oidc_proto_state_get_original_url (proto_state );
@@ -624,7 +625,7 @@ static int oidc_response_process(request_rec *r, oidc_cfg_t *c, oidc_session_t *
624625 const char * prompt = oidc_proto_state_get_prompt (proto_state );
625626
626627 /* set the user */
627- if (oidc_response_set_request_user (r , c , provider , jwt , claims ) == TRUE) {
628+ if (oidc_response_set_request_user (r , c , provider , id_token , userinfo_claims ) == TRUE) {
628629
629630 /* session management: if the user in the new response is not equal to the old one, error out */
630631 if ((prompt != NULL ) && (_oidc_strcmp (prompt , OIDC_PROTO_PROMPT_NONE ) == 0 )) {
@@ -634,36 +635,41 @@ static int oidc_response_process(request_rec *r, oidc_cfg_t *c, oidc_session_t *
634635 // if (_oidc_strcmp(sub, jwt->payload.sub) != 0) {
635636 if (_oidc_strcmp (session -> remote_user , r -> user ) != 0 ) {
636637 oidc_warn (r , "user set from new id_token is different from current one" );
637- oidc_jwt_destroy (jwt );
638+ oidc_jwt_destroy (id_token );
639+ json_decref (userinfo_claims );
638640 return oidc_response_authorization_error (r , c , proto_state , "User changed!" , NULL );
639641 }
640642 }
641643
642644 /* store resolved information in the session */
643645 if (oidc_response_save_in_session (
644- r , c , session , provider , r -> user , apr_table_get (params , OIDC_PROTO_ID_TOKEN ), jwt , claims ,
645- apr_table_get (params , OIDC_PROTO_ACCESS_TOKEN ), apr_table_get (params , OIDC_PROTO_TOKEN_TYPE ),
646- expires_in , apr_table_get (params , OIDC_PROTO_REFRESH_TOKEN ),
647- apr_table_get (params , OIDC_PROTO_SCOPE ), apr_table_get (params , OIDC_PROTO_SESSION_STATE ),
648- apr_table_get (params , OIDC_PROTO_STATE ), original_url , userinfo_jwt ) == FALSE) {
646+ r , c , session , provider , r -> user , apr_table_get (params , OIDC_PROTO_ID_TOKEN ), id_token ,
647+ s_userinfo_claims , userinfo_claims , apr_table_get (params , OIDC_PROTO_ACCESS_TOKEN ),
648+ apr_table_get (params , OIDC_PROTO_TOKEN_TYPE ), expires_in ,
649+ apr_table_get (params , OIDC_PROTO_REFRESH_TOKEN ), apr_table_get (params , OIDC_PROTO_SCOPE ),
650+ apr_table_get (params , OIDC_PROTO_SESSION_STATE ), apr_table_get (params , OIDC_PROTO_STATE ),
651+ original_url , userinfo_jwt ) == FALSE) {
649652 oidc_proto_state_destroy (proto_state );
650- oidc_jwt_destroy (jwt );
653+ oidc_jwt_destroy (id_token );
654+ json_decref (userinfo_claims );
651655 return HTTP_INTERNAL_SERVER_ERROR ;
652656 }
653657
654658 oidc_debug (r , "set remote_user to \"%s\" in new session \"%s\"" , r -> user , session -> uuid );
655659
656660 } else {
657661 oidc_error (r , "remote user could not be set" );
658- oidc_jwt_destroy (jwt );
662+ oidc_jwt_destroy (id_token );
663+ json_decref (userinfo_claims );
659664 OIDC_METRICS_COUNTER_INC (r , c , OM_AUTHN_RESPONSE_ERROR_REMOTE_USER );
660665 return oidc_response_authorization_error (
661666 r , c , proto_state , "Remote user could not be set: contact the website administrator" , NULL );
662667 }
663668
664669 /* cleanup */
665670 oidc_proto_state_destroy (proto_state );
666- oidc_jwt_destroy (jwt );
671+ oidc_jwt_destroy (id_token );
672+ json_decref (userinfo_claims );
667673
668674 /* check that we've actually authenticated a user; functions as error handling for oidc_get_remote_user */
669675 if (r -> user == NULL ) {
0 commit comments