public async Task <GoodIdResponse> CollectAsync() { var sessionDataHandler = mServiceLocator.SessionDataHandler; var stateNonceHandler = mServiceLocator.StateNonceHandler; try { var goodIdServerConfig = mServiceLocator.ServerConfig; var requestFactory = mServiceLocator.RequestFactory; var method = mIncomingRequest.GetMethod(); // Check HTTP method - Only HTTP GET acceptable when OP retun to the RP if (method != IncomingRequest.Method.GET) { throw new GoodIdException($"Unexpected request method {method}!"); } if (!stateNonceHandler.ValidateState(mIncomingRequest.GetStringParameter("state"))) { throw new ValidationException("The received state is invalid."); } var authCode = mIncomingRequest.GetStringParameter("code"); // Handle error case if (string.IsNullOrEmpty(authCode)) { var error = mIncomingRequest.GetStringParameter("error"); if (string.IsNullOrEmpty(error)) { throw new GoodIdException("Neither code nor error parameter is set."); } var errorDescription = mIncomingRequest.GetStringParameter("error_description"); return(new GoodIdResponseError(error, errorDescription)); } // Session parameters var requestSourceJson = sessionDataHandler.GetVariableRawJson(SessionDataHandler.SESSION_KEY_REQUEST_SOURCE); var usedRedirectUri = sessionDataHandler.GetVariableString(SessionDataHandler.SESSION_KEY_USED_REDIRECT_URI); if (string.IsNullOrEmpty(requestSourceJson)) { throw new GoodIdException("Request source is not set in session!"); } if (string.IsNullOrEmpty(usedRedirectUri)) { throw new GoodIdException("Redirect uri is not set in session!"); } var tokenResponse = await requestFactory.CreateTokenRequest( goodIdServerConfig, mServiceLocator.Logger, mClientId, mClientSecret, usedRedirectUri, authCode, null ).ExecuteAsync(); var jwe = tokenResponse.IdTokenJwe; var requestJObject = await GetRequestJObjectAsync(requestSourceJson, mSigningKey); int?requestedMaxAge = requestJObject?["max_age"] != null ? (int?)requestJObject["max_age"] : null; var authTimeRequested = false; if (requestJObject["claims"] != null && requestJObject["claims"]["id_token"] != null && requestJObject["claims"]["id_token"]["auth_time"] != null && requestJObject["claims"]["id_token"]["auth_time"]["essential"] != null) { authTimeRequested |= (requestJObject["claims"]["id_token"]["auth_time"]["essential"].ToObject <bool>()) == true; } if (requestJObject["claims"] != null && requestJObject["claims"]["userinfo"] != null && requestJObject["claims"]["userinfo"]["auth_time"] != null && requestJObject["claims"]["userinfo"]["auth_time"]["essential"] != null) { authTimeRequested |= (requestJObject["claims"]["userinfo"]["auth_time"]["essential"].ToObject <bool>()) == true; } TokenExtractor tokenExtractor = mServiceLocator.GetTokenExtractor(mEncryptionKeys); JObject idToken = tokenExtractor.ExtractToken(jwe); var idTokenVerifier = mServiceLocator.getIdTokenVerifier( idToken, mClientId, requestedMaxAge, authTimeRequested, stateNonceHandler.getCurrentNonce()); idTokenVerifier.Verify(); if (tokenResponse.AccessToken != null) { var accessToken = tokenResponse.AccessToken; var userinfoResponse = await requestFactory.CreateUserinfoRequest( goodIdServerConfig, accessToken ).ExecuteAsync(); JObject userinfo = tokenExtractor.ExtractToken(userinfoResponse.UserinfoJwe); var userinfoVerifier = mServiceLocator.GetUserinfoVerifier(idToken, userinfo); userinfoVerifier.Verify(); //TODO: matching validation var validator = mServiceLocator.ResponseValidator; validator.ValidateTokensBelongTogether(idToken, userinfo); if (mMatchingResponseValidation) { if (requestJObject != null && requestJObject["claims"] != null && requestJObject["claims"].Type == JTokenType.Object) { validator.ValidateMatchingResponse((JObject)requestJObject["claims"], userinfo); } else { throw new ValidationException("Matching response validation cannot succeed because the request object was probably encrypted, or nothing was requested."); } } var combined = MergeTokens(idToken, userinfo); return(new GoodIdResponseSuccess(accessToken, combined)); } else { throw new GoodIdException("You don't have access token."); } } catch (GoodIdException) { throw; } catch (Exception e) { throw new GoodIdException("Unknown error: " + e); } finally { sessionDataHandler.RemoveAllGoodIdVariables(); } }