private async Task <IAuthModel> ClientCredentialsGrant() { JWTModel authModel = new JWTModel(); try { using HttpClient client = this.httpClientService.CreateDefaultHttpClient(); IEnumerable <KeyValuePair <string, string> > oauthParams = new[] { new KeyValuePair <string, string>(@"client_id", this.TokenRequest.ClientId), new KeyValuePair <string, string>(@"client_secret", this.TokenRequest.ClientSecret), new KeyValuePair <string, string>(@"audience", this.TokenRequest.Audience), new KeyValuePair <string, string>(@"grant_type", @"client_credentials"), }; using var content = new FormUrlEncodedContent(oauthParams); content.Headers.Clear(); content.Headers.Add(@"Content-Type", @"application/x-www-form-urlencoded"); using HttpResponseMessage response = await client.PostAsync(this.TokenUri, content).ConfigureAwait(true); string jwtTokenResponse = await response.Content.ReadAsStringAsync().ConfigureAwait(true); this.logger.LogTrace($"JWT Token response: {jwtTokenResponse}"); response.EnsureSuccessStatusCode(); authModel = JsonSerializer.Deserialize <JWTModel>(jwtTokenResponse) !; } catch (HttpRequestException e) { this.logger.LogError($"Error Message {e.Message}"); } return(authModel); }
private void LogAndDipatchAuthResult(JWTModel result) { if (result == null) { throw new InvalidOperationException($"Encountered invalid {nameof(JWTModel)} after authentication."); } if (result.isTokenValid) { if (Logger.IsDebugEnabled) { Logger.Debug($"Recieved a valid JWT access token."); } OnSuccessfulAuthentication?.Invoke(); } else { if (Logger.IsDebugEnabled) { Logger.Debug($"Failed to authenticate. {result.Error}: {result.ErrorDescription}."); } OnFailedAuthentication?.Invoke($"Failed to authenticate. {result.Error}: {result.ErrorDescription}."); } }
//basicKey + [appsettings.json => Secret] to generate Unique-Token public ActionResult <IEnumerable <string> > GetJWT(string basicKey) { var jwtStr = string.Empty; var status = string.Empty; if (string.IsNullOrEmpty(basicKey)) { return(new JsonResult(new { Status = "Fail", message = "Please input basicKey in the end of 'api/JWT/GetJWT' to generete token!" })); } JWTModel jwtModel = new JWTModel() { UId = 1, Role = "Admin", }; jwtStr = JWTCore.GenerateJWT(jwtModel); status = "Success"; return(Ok(new { status = status, token = jwtStr })); }
/// <inheritdoc/> public async Task <List <MedicationStatement> > GetMedicationsAsync(string phn, string userId, string ipAddress) { JWTModel jwtModel = this.AuthenticateService(); using (HttpClient client = this.httpClientFactory.CreateClient("medicationService")) { client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue(MediaTypeNames.Application.Json)); client.BaseAddress = new Uri(this.configService.GetSection("HNClient")?.GetValue <string>("Url")); client.DefaultRequestHeaders.Add("Authorization", "Bearer " + jwtModel.AccessToken); HNMessage requestMessage = this.medicationParser.CreateRequestMessage(phn, userId, ipAddress); HttpResponseMessage response = await client.PostAsJsonAsync("v1/api/HNClient", requestMessage).ConfigureAwait(true); if (response.IsSuccessStatusCode) { string payload = await response.Content.ReadAsStringAsync().ConfigureAwait(true); HNMessage responseMessage = JsonConvert.DeserializeObject <HNMessage>(payload); return(this.medicationParser.ParseResponseMessage(responseMessage.Message)); } else { throw new HttpRequestException($"Unable to connect to HNClient: ${response.StatusCode}"); } } }
private void SendSessionClaimRequest(JWTModel model) { //Now we must hand write the session claim packet stream.putShort((short)model.AccessToken.Length + 2 + 1); //2 bytes for the length prefixed access token and 1 for the opcode. stream.put((byte)RsClientNetworkOperationCode.SessionClaimRequest); stream.putString(model.AccessToken); }
public void Process() { DateTime deleteDate = DateTime.UtcNow.AddHours(this.hoursBeforeDeletion); this.logger.LogInformation($"Looking for closed accounts that are earlier than {deleteDate}"); int page = 0; DBResult <List <UserProfile> > profileResult; do { profileResult = this.profileDelegate.GetClosedProfiles(deleteDate, page, this.profilesPageSize); foreach (UserProfile profile in profileResult.Payload) { this.dbContext.UserProfile.Remove(profile); if (!string.IsNullOrWhiteSpace(profile.Email)) { this.emailService.QueueNewEmail(profile.Email !, this.emailTemplate, false); } JWTModel jwtModel = this.authDelegate.AuthenticateAsSystem(); bool deleted = this.userAdminDelegate.DeleteUser(profile.IdentityManagementId !.Value, jwtModel); } this.logger.LogInformation($"Removed and sent emails for {profileResult.Payload.Count} closed profiles"); this.dbContext.SaveChanges(); // commit after every page page++; }while (profileResult.Payload.Count == this.profilesPageSize); this.logger.LogInformation($"Completed processing {page} page(s) with pagesize set to {this.profilesPageSize}"); }
/// <inheritdoc/> public JWTModel AuthenticateAsSystem() { this.logger.LogDebug($"Authenticating Service... {this.TokenRequest.ClientId}"); Task <IAuthModel> authenticating = this.ClientCredentialsGrant(); JWTModel jwtModel = (authenticating.Result as JWTModel) !; this.logger.LogDebug($"Finished authenticating Service. {this.TokenRequest.ClientId}"); return(jwtModel); }
/// <inheritdoc/> public JWTModel AuthenticateAsUser() { this.logger.LogDebug($"Authenticating Direct Grant as User: {this.TokenRequest.Username}"); Task <IAuthModel> authenticating = this.ResourceOwnerPasswordGrant(); JWTModel jwtModel = (authenticating.Result as JWTModel) !; this.logger.LogDebug($"Finished authenticating User: {this.TokenRequest.Username}"); return(jwtModel); }
public static void Test_JWTModel_Indicates_IsValid_When_Error_Is_Present(string error, string errorDescription) { //arrange JWTModel model = new JWTModel(error, errorDescription); //act JWTModel deserializedModel = JsonConvert.DeserializeObject <JWTModel>(JsonConvert.SerializeObject(model)); //assert Assert.IsFalse(deserializedModel.isTokenValid); }
public static void Test_JWTModel_Indicates_IsValid_When_AccessToken_IsPresent(string accessToken) { //arrange JWTModel model = new JWTModel(accessToken); //act JWTModel deserializedModel = JsonConvert.DeserializeObject <JWTModel>(JsonConvert.SerializeObject(model)); //assert Assert.IsTrue(deserializedModel.isTokenValid); }
public static void Test_Can_JSON_Serialize_Then_Deserialize_AccessToken(string accessToken) { //arrange JWTModel model = new JWTModel(accessToken); //act JWTModel deserializedModel = JsonConvert.DeserializeObject <JWTModel>(JsonConvert.SerializeObject(model)); //assert Assert.NotNull(deserializedModel); Assert.NotNull(deserializedModel.AccessToken); Assert.IsNotEmpty(deserializedModel.AccessToken); Assert.AreEqual(accessToken, deserializedModel.AccessToken); }
/// <inheritdoc/> public bool DeleteUser(Guid userId, JWTModel jwtModel) { this.logger.LogInformation($"Keycloak DeleteUser : {userId.ToString()}"); Task <bool> task = Task.Run(async() => await this.DeleteUserAsync(userId, jwtModel).ConfigureAwait(true)); task.Wait(); if (task.Exception != null) { throw task.Exception; } return(task.Result); }
public static void Test_Can_JSON_Serialize_To_NonNull_Non_Whitespace_ErrorArgs(string error, string errorDefinition) { //arrange JWTModel model = new JWTModel(error, errorDefinition); //act string serializedModel = JsonConvert.SerializeObject(model); //assert Assert.NotNull(serializedModel); Assert.IsNotEmpty(serializedModel); Assert.True(serializedModel.Contains(error)); Assert.True(serializedModel.Contains(errorDefinition)); }
public static void Test_Can_JSON_Serialize_Then_Deserialize_ErrorArgs(string error, string errorDefinition) { //arrange JWTModel model = new JWTModel(error, errorDefinition); //act JWTModel deserializedModel = JsonConvert.DeserializeObject <JWTModel>(JsonConvert.SerializeObject(model)); //assert Assert.NotNull(deserializedModel); Assert.NotNull(deserializedModel.Error); Assert.NotNull(deserializedModel.ErrorDescription); Assert.AreEqual(error, deserializedModel.Error); Assert.AreEqual(errorDefinition, deserializedModel.ErrorDescription); }
public static void Test_Can_JSON_Serialize_To_NonNull_Non_Whitespace_AccessToken(string accessToken) { //arrange JWTModel model = new JWTModel(accessToken); //act string serializedModel = JsonConvert.SerializeObject(model); //assert Assert.NotNull(serializedModel); Assert.True(!serializedModel.Contains(nameof(model.isTokenValid)), $"JSON modle contains what should be unlisted field {nameof(model.isTokenValid)}. JSON: {serializedModel}"); Assert.True(!serializedModel.Contains("_isTokenValid"), $"JSON modle contains what should be unlisted field _isTokenValid. JSON: {serializedModel}"); Assert.IsNotEmpty(serializedModel); Assert.True(serializedModel.Contains(accessToken)); }
public JsonResult CreateToken(string username, int timeOut) { DataResult result = new DataResult(); var jwtModel = new JWTModel(); jwtModel.UserName = username; jwtModel.Expiration = DateTime.Now.AddMilliseconds(timeOut);; result.Token = JwtHelper.EncodeJwt(jwtModel); result.Success = true; result.Message = "成功"; return(Json(result)); //get请求需要修改成这样 //return Json(result, JsonRequestBehavior.AllowGet); }
public void ShouldAuthenticateAsUser() { Uri tokenUri = new Uri("http://testsite"); ClientCredentialsTokenRequest tokenRequest = new ClientCredentialsTokenRequest() { ClientId = "CLIENT_ID", ClientSecret = "SOME_SECRET", Username = "******", Password = "******", }; string json = @"{ ""access_token"":""token"", ""expires_in"":500, ""refresh_expires_in"":0, ""refresh_token"":""refresh_token"", ""token_type"":""bearer"", ""not-before-policy"":25, ""session_state"":""session_state"", ""scope"":""scope"" }"; var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, IgnoreNullValues = true, WriteIndented = true, }; JWTModel expected = JsonSerializer.Deserialize <JWTModel>(json, options); using ILoggerFactory loggerFactory = LoggerFactory.Create(builder => builder.AddConsole()); ILogger <IAuthenticationDelegate> logger = loggerFactory.CreateLogger <IAuthenticationDelegate>(); var handlerMock = new Mock <HttpMessageHandler>(); handlerMock .Protected() .Setup <Task <HttpResponseMessage> >( "SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>() ) .ReturnsAsync(new HttpResponseMessage() { StatusCode = HttpStatusCode.OK, Content = new StringContent(json), }) .Verifiable(); Mock <IHttpClientService> mockHttpClientService = new Mock <IHttpClientService>(); mockHttpClientService.Setup(s => s.CreateDefaultHttpClient()).Returns(() => new HttpClient(handlerMock.Object)); IAuthenticationDelegate authDelegate = new AuthenticationDelegate(logger, mockHttpClientService.Object); JWTModel actualModel = authDelegate.AuthenticateAsUser(tokenUri, tokenRequest); Assert.True(actualModel.IsDeepEqual(expected)); }
/// <summary> /// Deletes the User account from Keycloak. /// </summary> /// <param name="userId">The user id to delete.</param> /// <param name="jwtModel">To get at the base64 access token.</param> /// <returns>returns true when user deleted.</returns> private async Task <bool> DeleteUserAsync(Guid userId, JWTModel jwtModel) { Uri baseUri = new Uri(this.configuration.GetSection(KEYCLOAKADMIN).GetValue <string>(DELETEUSERURL)); using HttpClient client = this.CreateHttpClient(baseUri, jwtModel.AccessToken !); HttpResponseMessage response = await client.DeleteAsync(new Uri(userId !.ToString(), UriKind.Relative)).ConfigureAwait(true); if (!response.IsSuccessStatusCode) { string msg = $"Error performing DELETE Request: {userId}, HTTP StatusCode: {response.StatusCode}"; this.logger.LogError(msg); throw new HttpRequestException(msg); } return(true); }
public async Task <bool> ValidateAsync(string jwt) { if (string.IsNullOrEmpty(jwt)) { return(false); } RequestSender requestSender = new RequestSender(); JWTModel token = new JWTModel(); token.token = jwt; var res = await requestSender.Post("auth/validate", token); if (res.StatusCode == HttpStatusCode.OK) { return(true); } return(false); }
} = "FN4rnejdE4jNDKW495jhhdDFRRR34d=="; // This secret key should be in WebConfig. /// <summary> /// Generates token . /// Validates whether the given model is valid, then gets the symmetric key. /// Encrypt the token and returns it. /// <remarks>At least one claim is Required</remarks> /// </summary> /// <param name="model"></param> /// <returns>Generated token.</returns> public string GenerateToken(JWTModel model) { if (model?.Claims == null || model.Claims.Length == 0) { throw new ArgumentException("Arguments to create token are not valid."); } var securityTokenDescriptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(model.Claims), Expires = DateTime.UtcNow.AddMinutes(Convert.ToInt32(model.ExpireMinutes)), SigningCredentials = new SigningCredentials(GetSymmetricSecurityKey(), model.SecurityAlgorithm) }; var jwtSecurityTokenHandler = new JwtSecurityTokenHandler(); var securityToken = jwtSecurityTokenHandler.CreateToken(securityTokenDescriptor); var token = jwtSecurityTokenHandler.WriteToken(securityToken); return(token); }
//Check JWT digital signature and role claim protected override bool IsAuthorized(HttpActionContext actionContext) { JWTModel model = new JWTModel(); JWTService jwtService = new JWTService(model.PrivateKey, model.PublicKey); IEnumerable <Claim> claims; var authToken = actionContext.Request.Headers.Authorization.Parameter; string role; try { claims = jwtService.GetTokenClaims(authToken); } catch (Exception) { return(false); } role = claims.First(c => c.Type == ClaimTypes.Role).Value; return(AllowedRoles.Any(r => r == role)); }
private bool Authenticate() { //https://stackoverflow.com/questions/4926676/mono-https-webrequest-fails-with-the-authentication-or-decryption-has-failed ServicePointManager.ServerCertificateValidationCallback = MyRemoteCertificateValidationCallback; //TODO: Service discovery IAuthenticationService authService = TypeSafeHttpBuilder <IAuthenticationService> .Create() .RegisterDefaultSerializers() .RegisterDotNetHttpClient("https://localhost:5001/") .RegisterJsonNetSerializer() .Build(); //Authentication using provided credentials JWTModel result = authService.TryAuthenticate(new AuthenticationRequestModel(AccountName, Password)).Result; Debug.Log($"Auth Result: {result.isTokenValid} Token: {result.AccessToken} Error: {result.Error} ErrorDescription: {result.ErrorDescription}."); AuthToken = $"Bearer {result.AccessToken}"; return(result.isTokenValid); }
public IHttpActionResult Login([FromBody] UserLoginModel user) { // If model is Invalid return failed login. if (!ModelState.IsValid) { return(BadRequest(ModelState)); } if (AccountBll.Login(user)) { var jwtservice = new JWTService(); var jwtmodel = JWTModel.GetJWTContainerModel(user.Email); var token = jwtservice.GenerateToken(jwtmodel); var dict = new Dictionary <string, string>(); dict.Add("token", token); return(Content(HttpStatusCode.OK, dict, new JsonMediaTypeFormatter())); } return(Content(HttpStatusCode.BadRequest, new MessageStatus() { Code = "500", Message = "Login Failed" }, new JsonMediaTypeFormatter())); }
/// <inheritdoc/> public async Task <IAuthModel> ClientCredentialsAuth() { JWTModel authModel = new JWTModel(); try { using (HttpClient client = new HttpClient()) { // Create content for keycloak IEnumerable <KeyValuePair <string, string> > keycloakParams = new[] { new KeyValuePair <string, string>("client_id", this.TokenRequest.ClientId), new KeyValuePair <string, string>("client_secret", this.TokenRequest.ClientSecret), new KeyValuePair <string, string>("audience", this.TokenRequest.Audience), new KeyValuePair <string, string>("grant_type", @"client_credentials"), }; using (var content = new FormUrlEncodedContent(keycloakParams)) { content.Headers.Clear(); content.Headers.Add("Content-Type", "application/x-www-form-urlencoded"); using (HttpResponseMessage response = await client.PostAsync(this.TokenUri, content).ConfigureAwait(true)) { response.EnsureSuccessStatusCode(); var jwtTokenResponse = await response.Content.ReadAsStringAsync().ConfigureAwait(true); authModel = JsonConvert.DeserializeObject <JWTModel>(jwtTokenResponse); } } } } catch (HttpRequestException e) { Console.WriteLine($"Error Message ${e.Message}"); } return(authModel); }
//TODO: This is just initial/demo code. We need a real and proper implementation. protected override void HandleClientAuthentication(string playerUsername, string playerPassword, bool recoveredConnection) { //Dev hack to enable HTTPS for now. ServicePointManager.ServerCertificateValidationCallback += (o, c, ch, er) => true; ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; ServicePointManager.CheckCertificateRevocationList = false; //TODO: Implement service discovery. IAuthenticationService service = RestService.For <IAuthenticationService>("https://auth.vrguardians.net/"); JWTModel model = service.TryAuthenticate(new AuthenticationRequestModel(playerUsername, playerPassword)) .ConfigureAwait(false).GetAwaiter().GetResult(); Console.WriteLine($"Authentication Result: {model.isTokenValid} OptionalError: {model.Error}"); if (model.isTokenValid) { ConnectToGameServer(); HandleLoginSuccessful(2, false); SendSessionClaimRequest(model); } }
protected override bool IsAuthorized(HttpActionContext actionContext) { JWTModel model = new JWTModel(); JWTService jwtService = new JWTService(model.PrivateKey, model.PublicKey); IEnumerable <Claim> claims; string clientId; try { var authToken = actionContext.Request.Headers.Authorization.Parameter; var length = actionContext.Request.RequestUri.Segments.Count(); string userId = actionContext.Request.RequestUri.Segments[length - 1]; claims = jwtService.GetTokenClaims(authToken); clientId = claims.First(c => c.Type == "user-id").Value; return(clientId == userId); } catch (Exception) { return(false); } }
public string Create(Action <JWTModel> action) { JWTModel model = new JWTModel(); action.Invoke(obj: model); int currentHour = DateTime.Today.Hour; int remainHourtoMidNight = model.ExpiresAtMidnight ? (24 - currentHour) : 0; byte[] secretKey = Encoding.ASCII.GetBytes(model.SecretKey); JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler(); ClaimsIdentity claimsIdentity = new ClaimsIdentity(model.Claims); SecurityTokenDescriptor tokenDescriptor = new SecurityTokenDescriptor { Subject = claimsIdentity, Expires = DateTime.UtcNow.AddDays(model.ExpiresDate).AddHours(remainHourtoMidNight), SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(secretKey), model.SecurityAlgorithms) }; SecurityToken token = tokenHandler.CreateToken(tokenDescriptor); return(tokenHandler.WriteToken(token)); }
protected override bool AuthorizeCore(HttpContextBase httpContext) { var token = httpContext.Request.Headers["x-wps-weboffice-token"]; JWTModel jwtModel = JwtHelper.DecodeJwt(token); LogHelper.Default.WriteInfo($"开始进入验证用户过滤器,用户是:{jwtModel.UserName},过期时间是:{jwtModel.Expiration}"); if (jwtModel.UserName != "天玺") { LogHelper.Default.WriteInfo("过滤器返回【false】"); return(false); } if (jwtModel.Expiration < DateTime.Now) { LogHelper.Default.WriteInfo("过滤器返回【false】"); return(false); } //var result = new RequestParam(); //result.FileId = httpContext.Request.Headers["x-weboffice-file-id"].ToString(); //var queryStr = httpContext.Request.QueryString.ToString(); //queryStr = queryStr.StartsWith("?") ? queryStr.Substring(1) : queryStr; //if (string.IsNullOrEmpty(queryStr) || string.IsNullOrEmpty(result.FileId)) //{ // return false; //} //result.Params = queryStr.Split(new char[1] { '&' }, StringSplitOptions.RemoveEmptyEntries).ToDictionary(p => p.Split('=')[0], p => p.Split('=')[1]); // 此处判断是否传递了自定义的 _w_userId 参数,如果不需要此参数的话可以注释该判断 //if (!result.Params.ContainsKey("_w_userId")) //{ // return false; //} LogHelper.Default.WriteInfo("过滤器返回【true】"); return(true); }
public Task AddToken(JWTModel model) { throw new NotImplementedException(); }
public void ShouldRetrieveMedicationRequests() { // Setup // Input Parameters string phn = "9735361219"; // Setup Configuration string endpoint = "https://test-endpoint"; Uri tokenUri = new Uri("https://localhost"); ClientCredentialsTokenRequest tokenRequest = new ClientCredentialsTokenRequest() { ClientId = "TEST_CLIENTID", ClientSecret = "TEST_CLIENT_SECRET", Password = "******", Username = "******", }; Dictionary <string, string> configurationParams = new Dictionary <string, string> { { "Salesforce:Endpoint", endpoint }, { "Salesforce:TokenUri", tokenUri.ToString() }, { "Salesforce:ClientAuthentication:ClientId", tokenRequest.ClientId }, { "Salesforce:ClientAuthentication:ClientSecret", tokenRequest.ClientSecret }, { "Salesforce:ClientAuthentication:Username", tokenRequest.Username }, { "Salesforce:ClientAuthentication:Password", tokenRequest.Password }, }; IConfiguration configuration = CreateConfiguration(configurationParams); // Setup Authentication string jwtJson = @"{ ""access_token"":""token"", ""expires_in"":500, ""refresh_expires_in"":0, ""refresh_token"":""refresh_token"", ""token_type"":""bearer"", ""not-before-policy"":25, ""session_state"":""session_state"", ""scope"":""scope"" }"; JWTModel authorizationJWT = CreateJWTModel(jwtJson); Mock <IAuthenticationDelegate> mockAuthenticationDelegate = new Mock <IAuthenticationDelegate>(); mockAuthenticationDelegate .Setup(s => s.AuthenticateAsUser( It.Is <Uri>(x => x.ToString() == tokenUri.ToString()), It.Is <ClientCredentialsTokenRequest>(x => x.ClientId == tokenRequest.ClientId))) .Returns(() => authorizationJWT); // Setup Http response using HttpResponseMessage httpResponseMessage = new HttpResponseMessage() { StatusCode = HttpStatusCode.OK, Content = new StringContent("{\"items\":[{\"requestStatus\":\"Approved\",\"requestedDate\":\"2020-11-13T00:00:00.000Z\",\"referenceNumber\":\"00001046\",\"prescriberLastName\":\"Provider\",\"prescriberFirstName\":\"Test\",\"patientLastName\":null,\"patientIdentifier\":null,\"patientFirstName\":null,\"expiryDate\":null,\"effectiveDate\":null,\"drugName\":\"rabeprazole 10, 20 mg NB4\"},{\"requestStatus\":\"Approved\",\"requestedDate\":\"2020-11-15T00:00:00.000Z\",\"referenceNumber\":\"00001048\",\"prescriberLastName\":null,\"prescriberFirstName\":null,\"patientLastName\":null,\"patientIdentifier\":null,\"patientFirstName\":null,\"expiryDate\":null,\"effectiveDate\":\"2021-02-17\",\"drugName\":\"abatacept w/e name here\"},{\"requestStatus\":\"Received\",\"requestedDate\":\"2020-11-15T00:00:00.000Z\",\"referenceNumber\":\"00001047\",\"prescriberLastName\":null,\"prescriberFirstName\":null,\"patientLastName\":null,\"patientIdentifier\":null,\"patientFirstName\":null,\"expiryDate\":null,\"effectiveDate\":null,\"drugName\":\"depakote sprinkle cap 125mg (SAP)\"}]}"), }; Mock <IHttpClientService> mockHttpClient = CreateHttpClient(httpResponseMessage, phn, authorizationJWT?.AccessToken); // Setup class to be tested IMedicationRequestDelegate medDelegate = new SalesforeceDelegate( CreateLogger(), mockHttpClient.Object, configuration, mockAuthenticationDelegate.Object); // Test RequestResult <IList <MedicationRequest> > response = Task.Run(async() => await medDelegate.GetMedicationRequestsAsync(phn).ConfigureAwait(true)).Result; // Verify Assert.Equal(Common.Constants.ResultType.Success, response.ResultStatus); Assert.Equal(3, response.TotalResultCount); Assert.Equal(3, response.ResourcePayload?.Count); }