public static AuthenticationResult ParseTokenResponse(TokenResponse tokenResponse, CallState callState)
        {
            AuthenticationResult result;

            if (tokenResponse.AccessToken != null)
            {
                DateTimeOffset expiresOn = DateTime.UtcNow + TimeSpan.FromSeconds(tokenResponse.ExpiresIn);

                result = new AuthenticationResult(tokenResponse.TokenType, tokenResponse.AccessToken, tokenResponse.RefreshToken, expiresOn)
                    {
#if ADAL_NET
                        // This is only needed for AcquireTokenByAuthorizationCode in which parameter resource is optional and we need
                        // to get it from the STS response.
                        Resource = tokenResponse.Resource,
#endif                        
                    };

                IdToken idToken = ParseIdToken(tokenResponse.IdToken);
                if (idToken != null)
                {
                    string tenantId = idToken.TenantId;
                    string uniqueId = null;
                    string displayableId = null;

                    if (!string.IsNullOrWhiteSpace(idToken.ObjectId))
                    {
                        uniqueId = idToken.ObjectId;
                    }
                    else if (!string.IsNullOrWhiteSpace(idToken.Subject))
                    {
                        uniqueId = idToken.Subject;
                    }

                    if (!string.IsNullOrWhiteSpace(idToken.UPN))
                    {
                        displayableId = idToken.UPN;
                    }
                    else if (!string.IsNullOrWhiteSpace(idToken.Email))
                    {
                        displayableId = idToken.Email;
                    }

                    string givenName = idToken.GivenName;
                    string familyName = idToken.FamilyName;
                    string identityProvider = idToken.IdentityProvider ?? idToken.Issuer;
                    DateTimeOffset? passwordExpiresOffest = null;
                    if (idToken.PasswordExpiration > 0)
                    {
                        passwordExpiresOffest = DateTime.UtcNow + TimeSpan.FromSeconds(idToken.PasswordExpiration);
                    }

                    Uri changePasswordUri = null;
                    if (!string.IsNullOrEmpty(idToken.PasswordChangeUrl))
                    {
                        changePasswordUri = new Uri(idToken.PasswordChangeUrl);
                    }

                    result.UpdateTenantAndUserInfo(tenantId, tokenResponse.IdToken, new UserInfo { UniqueId = uniqueId, DisplayableId = displayableId, GivenName = givenName, FamilyName = familyName, IdentityProvider = identityProvider, PasswordExpiresOn = passwordExpiresOffest, PasswordChangeUrl = changePasswordUri });
                }
            }
            else if (tokenResponse.Error != null)
            {
                throw new AdalServiceException(tokenResponse.Error, tokenResponse.ErrorDescription);
            }
            else
            {
                throw new AdalServiceException(AdalError.Unknown, AdalErrorMessage.Unknown);
            }

            return result;
        }
        public static TokenResponse ReadErrorResponse(WebResponse response)
        {
            if (response == null)
            {
                return new TokenResponse 
                    { 
                        Error = AdalError.ServiceReturnedError,
                        ErrorDescription = AdalErrorMessage.ServiceReturnedError 
                    };
            }

            Stream responseStream = response.GetResponseStream();

            if (responseStream == null)
            {
                return new TokenResponse 
                    { 
                        Error = AdalError.Unknown, 
                        ErrorDescription = AdalErrorMessage.Unknown 
                    };
            }

            TokenResponse tokenResponse;
            StringBuilder responseStreamString = new StringBuilder();
            try
            {
                responseStreamString.Append(HttpHelper.ReadStreamContent(responseStream));
                using (MemoryStream ms = new MemoryStream(responseStreamString.ToByteArray()))
                {
                    DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof (TokenResponse));
                    tokenResponse = ((TokenResponse) serializer.ReadObject(ms));
                }
            }
            catch (SerializationException)
            {
                tokenResponse = new TokenResponse
                {
                    Error = (((HttpWebResponse)response).StatusCode == HttpStatusCode.ServiceUnavailable) ? 
                        AdalError.ServiceUnavailable : 
                        AdalError.Unknown,
                    ErrorDescription = responseStreamString.ToString()
                };
            }

            return tokenResponse;
        }
        public static TokenResponse ReadErrorResponse(WebResponse response)
        {
            if (response == null)
            {
                return new TokenResponse 
                    { 
                        Error = AdalError.ServiceReturnedError,
                        ErrorDescription = AdalErrorMessage.ServiceReturnedError 
                    };
            }

            Stream responseStream = response.GetResponseStream();

            if (responseStream == null)
            {
                return new TokenResponse 
                    { 
                        Error = AdalError.Unknown, 
                        ErrorDescription = AdalErrorMessage.Unknown 
                    };
            }

            TokenResponse tokenResponse;

            try
            {
                DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(TokenResponse));
                tokenResponse = ((TokenResponse)serializer.ReadObject(responseStream));

                // Reset stream position to make it possible for application to read WebException body again
                responseStream.Position = 0;
            }
            catch (SerializationException)
            {
                responseStream.Position = 0;
                tokenResponse = new TokenResponse
                {
                    Error = (((HttpWebResponse)response).StatusCode == HttpStatusCode.ServiceUnavailable) ? 
                        AdalError.ServiceUnavailable : 
                        AdalError.Unknown,
                    ErrorDescription = HttpHelper.ReadStreamContent(responseStream)
                };
            }

            return tokenResponse;
        }
 private TokenResponse CreateTokenResponse()
 {
     TokenResponse tr = new TokenResponse();
     tr.AccessToken = "access_token";
     tr.RefreshToken = "refresh_token";
     tr.CorrelationId = Guid.NewGuid().ToString();
     tr.Resource = "my-resource";
     tr.TokenType = "Bearer";
     tr.ExpiresIn = 3899;
     tr.ExpiresOn = 1400545595;
     return tr;
 }
        public static AuthenticationResult ParseTokenResponse(TokenResponse tokenResponse, CallState callState)
        {
            AuthenticationResult result;

            if (tokenResponse.AccessToken != null)
            {
                DateTimeOffset expiresOn = DateTime.UtcNow + TimeSpan.FromSeconds(tokenResponse.ExpiresIn);

                result = new AuthenticationResult(tokenResponse.TokenType, tokenResponse.AccessToken, tokenResponse.RefreshToken, expiresOn)
                {
#if ADAL_NET
                    // This is only needed for AcquireTokenByAuthorizationCode in which parameter resource is optional and we need
                    // to get it from the STS response.
                    Resource = tokenResponse.Resource,
#endif
                };

                IdToken idToken = ParseIdToken(tokenResponse.IdToken);
                if (idToken != null)
                {
                    string tenantId      = idToken.TenantId;
                    string uniqueId      = null;
                    string displayableId = null;

                    if (!string.IsNullOrWhiteSpace(idToken.ObjectId))
                    {
                        uniqueId = idToken.ObjectId;
                    }
                    else if (!string.IsNullOrWhiteSpace(idToken.Subject))
                    {
                        uniqueId = idToken.Subject;
                    }

                    if (!string.IsNullOrWhiteSpace(idToken.UPN))
                    {
                        displayableId = idToken.UPN;
                    }
                    else if (!string.IsNullOrWhiteSpace(idToken.Email))
                    {
                        displayableId = idToken.Email;
                    }

                    string         givenName             = idToken.GivenName;
                    string         familyName            = idToken.FamilyName;
                    string         identityProvider      = idToken.IdentityProvider ?? idToken.Issuer;
                    DateTimeOffset?passwordExpiresOffest = null;
                    if (idToken.PasswordExpiration > 0)
                    {
                        passwordExpiresOffest = DateTime.UtcNow + TimeSpan.FromSeconds(idToken.PasswordExpiration);
                    }

                    Uri changePasswordUri = null;
                    if (!string.IsNullOrEmpty(idToken.PasswordChangeUrl))
                    {
                        changePasswordUri = new Uri(idToken.PasswordChangeUrl);
                    }

                    result.UpdateTenantAndUserInfo(tenantId, tokenResponse.IdToken, new UserInfo {
                        UniqueId = uniqueId, DisplayableId = displayableId, GivenName = givenName, FamilyName = familyName, IdentityProvider = identityProvider, PasswordExpiresOn = passwordExpiresOffest, PasswordChangeUrl = changePasswordUri
                    });
                }
            }
            else if (tokenResponse.Error != null)
            {
                throw new AdalServiceException(tokenResponse.Error, tokenResponse.ErrorDescription);
            }
            else
            {
                throw new AdalServiceException(AdalError.Unknown, AdalErrorMessage.Unknown);
            }

            return(result);
        }
Example #6
0
        private async Task <T> GetResponseAsync <T>(bool respondToDeviceAuthChallenge)
        {
            T typedResponse = default(T);
            IHttpWebResponse response;

            try
            {
                if (PlatformPlugin.HttpClientFactory.AddAdditionalHeaders)
                {
                    IDictionary <string, string> adalIdHeaders = AdalIdHelper.GetAdalIdParameters();
                    foreach (KeyValuePair <string, string> kvp in adalIdHeaders)
                    {
                        this.Client.Headers[kvp.Key] = kvp.Value;
                    }
                }

                //add pkeyauth header
                this.Client.Headers[DeviceAuthHeaderName] = DeviceAuthHeaderValue;
                using (response = await this.Client.GetResponseAsync().ConfigureAwait(false))
                {
                    typedResponse = EncodingHelper.DeserializeResponse <T>(response.ResponseString);
                }
            }
            catch (HttpRequestWrapperException ex)
            {
                if (ex.InnerException is TaskCanceledException)
                {
                    Resiliency = true;
                    PlatformPlugin.Logger.Information(this.CallState, "Network timeout - " + ex.InnerException.Message);
                }

                if (!this.isDeviceAuthChallenge(ex.WebResponse, respondToDeviceAuthChallenge))
                {
                    AdalServiceException serviceEx;
                    if (ex.WebResponse != null)
                    {
                        TokenResponse tokenResponse = TokenResponse.CreateFromErrorResponse(ex.WebResponse);
                        string[]      errorCodes    = tokenResponse.ErrorCodes ?? new[] { ex.WebResponse.StatusCode.ToString() };
                        serviceEx = new AdalServiceException(tokenResponse.Error, tokenResponse.ErrorDescription,
                                                             errorCodes, ex);

                        if ((ex.WebResponse.StatusCode.Equals(HttpStatusCode.InternalServerError)) ||
                            (ex.WebResponse.StatusCode).Equals(HttpStatusCode.GatewayTimeout) ||
                            (ex.WebResponse.StatusCode).Equals(HttpStatusCode.ServiceUnavailable))
                        {
                            PlatformPlugin.Logger.Information(this.CallState, "HttpStatus code: " + ex.WebResponse.StatusCode + " - " + ex.InnerException.Message);
                            Resiliency = true;
                        }
                    }
                    else
                    {
                        serviceEx = new AdalServiceException(AdalError.Unknown, ex);
                    }

                    if (Resiliency)
                    {
                        if (RetryOnce)
                        {
                            await Task.Delay(DelayTimePeriodMilliSeconds).ConfigureAwait(false);

                            RetryOnce = false;
                            PlatformPlugin.Logger.Information(this.CallState, "Retrying one more time..");
                            return(await this.GetResponseAsync <T>(respondToDeviceAuthChallenge).ConfigureAwait(false));
                        }

                        PlatformPlugin.Logger.Information(this.CallState,
                                                          "Retry Failed - " + ex.InnerException.Message);
                    }

                    PlatformPlugin.Logger.Error(CallState, serviceEx);
                    throw serviceEx;
                }
                else
                {
                    response = ex.WebResponse;
                }
            }
            //check for pkeyauth challenge
            if (this.isDeviceAuthChallenge(response, respondToDeviceAuthChallenge))
            {
                return(await HandleDeviceAuthChallenge <T>(response).ConfigureAwait(false));
            }

            return(typedResponse);
        }
        private async Task <T> GetResponseAsync <T>(string endpointType, bool respondToDeviceAuthChallenge)
        {
            T typedResponse = default(T);
            IHttpWebResponse response;
            ClientMetrics    clientMetrics = new ClientMetrics();

            try
            {
                clientMetrics.BeginClientMetricsRecord(this.CallState);

                if (PlatformPlugin.HttpClientFactory.AddAdditionalHeaders)
                {
                    Dictionary <string, string> clientMetricsHeaders = clientMetrics.GetPreviousRequestRecord(this.CallState);
                    foreach (KeyValuePair <string, string> kvp in clientMetricsHeaders)
                    {
                        this.Client.Headers[kvp.Key] = kvp.Value;
                    }

                    IDictionary <string, string> adalIdHeaders = AdalIdHelper.GetAdalIdParameters();
                    foreach (KeyValuePair <string, string> kvp in adalIdHeaders)
                    {
                        this.Client.Headers[kvp.Key] = kvp.Value;
                    }
                }

                //add pkeyauth header
                this.Client.Headers[DeviceAuthHeaderName] = DeviceAuthHeaderValue;
                using (response = await this.Client.GetResponseAsync())
                {
                    typedResponse = DeserializeResponse <T>(response.ResponseStream);
                    clientMetrics.SetLastError(null);
                }
            }
            catch (HttpRequestWrapperException ex)
            {
                if (!this.isDeviceAuthChallenge(endpointType, ex.WebResponse, respondToDeviceAuthChallenge))
                {
                    AdalServiceException serviceEx;
                    if (ex.WebResponse != null)
                    {
                        TokenResponse tokenResponse = TokenResponse.CreateFromErrorResponse(ex.WebResponse);
                        string[]      errorCodes    = tokenResponse.ErrorCodes ?? new[] { ex.WebResponse.StatusCode.ToString() };
                        serviceEx = new AdalServiceException(tokenResponse.Error, tokenResponse.ErrorDescription,
                                                             errorCodes, ex);
                    }
                    else
                    {
                        serviceEx = new AdalServiceException(AdalError.Unknown, ex);
                    }

                    clientMetrics.SetLastError(serviceEx.ServiceErrorCodes);
                    PlatformPlugin.Logger.Error(CallState, serviceEx);
                    throw serviceEx;
                }
                else
                {
                    response = ex.WebResponse;
                }
            }
            finally
            {
                clientMetrics.EndClientMetricsRecord(endpointType, this.CallState);
            }

            //check for pkeyauth challenge
            if (this.isDeviceAuthChallenge(endpointType, response, respondToDeviceAuthChallenge))
            {
                return(await HandleDeviceAuthChallenge <T>(endpointType, response));
            }

            return(typedResponse);
        }