@@ -830,6 +830,51 @@ local function openidc_load_jwt_and_verify_crypto(opts, jwt_string, asymmetric_s
830830 return jwt_obj
831831end
832832
833+ --
834+ -- Load and validate id token from the id_token properties of the token endpoint response
835+ -- Parameters :
836+ -- - opts the openidc module options
837+ -- - jwt_id_token the id_token from the id_token properties of the token endpoint response
838+ -- - session the current session
839+ -- Return the id_token, nil if valid
840+ -- Return nil, the error if invalid
841+ --
842+ local function openidc_load_and_validate_jwt_id_token (opts , jwt_id_token , session )
843+
844+ local jwt_obj , err = openidc_load_jwt_and_verify_crypto (opts , jwt_id_token , opts .secret , opts .client_secret ,
845+ opts .discovery .id_token_signing_alg_values_supported )
846+ if err then
847+ local alg = (jwt_obj and jwt_obj .header and jwt_obj .header .alg ) or ' '
848+ local is_unsupported_signature_error = jwt_obj and not jwt_obj .verified and not is_algorithm_supported (jwt_obj .header )
849+ if is_unsupported_signature_error then
850+ if opts .accept_unsupported_alg == nil or opts .accept_unsupported_alg then
851+ ngx .log (ngx .WARN , " ignored id_token signature as algorithm '" .. alg .. " ' is not supported" )
852+ else
853+ err = " token is signed using algorithm \" " .. alg .. " \" which is not supported by lua-resty-jwt"
854+ ngx .log (ngx .ERR , err )
855+ return nil , err
856+ end
857+ else
858+ ngx .log (ngx .ERR , " id_token '" .. alg .. " ' signature verification failed" )
859+ return nil , err
860+ end
861+ end
862+ local id_token = jwt_obj .payload
863+
864+ ngx .log (ngx .DEBUG , " id_token header: " , cjson .encode (jwt_obj .header ))
865+ ngx .log (ngx .DEBUG , " id_token payload: " , cjson .encode (jwt_obj .payload ))
866+
867+ -- validate the id_token contents
868+ if openidc_validate_id_token (opts , id_token , session .data .nonce ) == false then
869+ err = " id_token validation failed"
870+ ngx .log (ngx .ERR , err )
871+ return nil , err
872+ end
873+
874+ return id_token
875+
876+ end
877+
833878-- handle a "code" authorization response from the OP
834879local function openidc_authorization_response (opts , session )
835880 local args = ngx .req .get_uri_args ()
@@ -880,34 +925,8 @@ local function openidc_authorization_response(opts, session)
880925 return nil , err , session .data .original_url , session
881926 end
882927
883- local jwt_obj
884- jwt_obj , err = openidc_load_jwt_and_verify_crypto (opts , json .id_token , opts .secret , opts .client_secret ,
885- opts .discovery .id_token_signing_alg_values_supported )
928+ local id_token , err = openidc_load_and_validate_jwt_id_token (opts , json .id_token , session );
886929 if err then
887- local alg = (jwt_obj and jwt_obj .header and jwt_obj .header .alg ) or ' '
888- local is_unsupported_signature_error = jwt_obj and not jwt_obj .verified and not is_algorithm_supported (jwt_obj .header )
889- if is_unsupported_signature_error then
890- if opts .accept_unsupported_alg == nil or opts .accept_unsupported_alg then
891- ngx .log (ngx .WARN , " ignored id_token signature as algorithm '" .. alg .. " ' is not supported" )
892- else
893- err = " token is signed using algorithm \" " .. alg .. " \" which is not supported by lua-resty-jwt"
894- ngx .log (ngx .ERR , err )
895- return nil , err , session .data .original_url , session
896- end
897- else
898- ngx .log (ngx .ERR , " id_token '" .. alg .. " ' signature verification failed" )
899- return nil , err , session .data .original_url , session
900- end
901- end
902- local id_token = jwt_obj .payload
903-
904- ngx .log (ngx .DEBUG , " id_token header: " , cjson .encode (jwt_obj .header ))
905- ngx .log (ngx .DEBUG , " id_token payload: " , cjson .encode (jwt_obj .payload ))
906-
907- -- validate the id_token contents
908- if openidc_validate_id_token (opts , id_token , session .data .nonce ) == false then
909- err = " id_token validation failed"
910- ngx .log (ngx .ERR , err )
911930 return nil , err , session .data .original_url , session
912931 end
913932
@@ -1090,16 +1109,35 @@ local function openidc_access_token(opts, session, try_to_renew)
10901109 if err then
10911110 return nil , err
10921111 end
1112+ local id_token
1113+ if json .id_token then
1114+ id_token , err = openidc_load_and_validate_jwt_id_token (opts , json .id_token , session )
1115+ if err then
1116+ ngx .log (ngx .ERR , " invalid id token, discarding tokens returned while refreshing" )
1117+ return nil , err
1118+ end
1119+ end
10931120 ngx .log (ngx .DEBUG , " access_token refreshed: " , json .access_token , " updated refresh_token: " , json .refresh_token )
10941121
10951122 session :start ()
10961123 session .data .access_token = json .access_token
10971124 session .data .access_token_expiration = current_time + openidc_access_token_expires_in (opts , json .expires_in )
1098- if json .refresh_token ~= nil then
1125+ if json .refresh_token then
10991126 session .data .refresh_token = json .refresh_token
11001127 end
11011128
1102- -- save the session with the new access_token and optionally the new refresh_token
1129+ if json .id_token and
1130+ (store_in_session (opts , ' enc_id_token' ) or store_in_session (opts , ' id_token' )) then
1131+ ngx .log (ngx .DEBUG , " id_token refreshed: " , json .id_token )
1132+ if store_in_session (opts , ' enc_id_token' ) then
1133+ session .data .enc_id_token = json .id_token
1134+ end
1135+ if store_in_session (opts , ' id_token' ) then
1136+ session .data .id_token = id_token
1137+ end
1138+ end
1139+
1140+ -- save the session with the new access_token and optionally the new refresh_token and id_token
11031141 session :save ()
11041142
11051143 return session .data .access_token , err
0 commit comments