Beispiel #1
0
 public async Task<AuthorizationResult> AcquireAuthorizationAsync(Uri authorizationUri, Uri redirectUri, CallState callState)
 {
     returnedUriReady = new SemaphoreSlim(0);
     Authenticate(authorizationUri, redirectUri, callState);
     await returnedUriReady.WaitAsync();
     return authorizationResult;
 }
 public ReplayerHttpClient(string uri, CallState callState)
 {
     this.internalHttpCilent = (new HttpClientFactory()).Create(uri, null);
     this.keyElements = new Dictionary<string, string>();
     this.keyElements["Uri"] = uri;
     this.CallState = callState;
 }
        public AuthorizationResult ProcessAuthorizationResult(IWebAuthenticationBrokerContinuationEventArgs args, CallState callState)
        {
            AuthorizationResult result;
            switch (args.WebAuthenticationResult.ResponseStatus)
            {
                case WebAuthenticationStatus.Success:
					// Issue #129 - Windows Phone cannot handle ms-app URI's so use the placeholder URI for SSO
					var responseData = args.WebAuthenticationResult.ResponseData;
					if(responseData.StartsWith(Constant.MsAppScheme, StringComparison.OrdinalIgnoreCase))
					{
						responseData = Constant.SsoPlaceHolderUri + responseData.Substring(responseData.IndexOf('?'));
					}

					result = OAuth2Response.ParseAuthorizeResponse(responseData, callState);
                    break;
                case WebAuthenticationStatus.ErrorHttp:
                    result = new AuthorizationResult(AdalError.AuthenticationFailed, args.WebAuthenticationResult.ResponseErrorDetail.ToString());
                    break;
                case WebAuthenticationStatus.UserCancel:
                    result = new AuthorizationResult(AdalError.AuthenticationCanceled, AdalErrorMessage.AuthenticationCanceled);
                    break;
                default:
                    result = new AuthorizationResult(AdalError.AuthenticationFailed, AdalErrorMessage.AuthorizationServerInvalidResponse);
                    break;
            }

            return result;
        }
 public void BeginClientMetricsRecord(CallState callState)
 {
     if (callState != null && callState.AuthorityType == AuthorityType.AAD)
     {
         metricsTimer = Stopwatch.StartNew();
     }
 }
        internal static Uri ExtractWsTrustAddressFromMex(XDocument mexDocument, UserAuthType userAuthType, CallState callState)
        {
            Uri url;

            try
            {
                Dictionary<string, MexPolicy> policies = ReadPolicies(mexDocument);
                Dictionary<string, MexPolicy> bindings = ReadPolicyBindings(mexDocument, policies);
                SetPolicyEndpointAddresses(mexDocument, bindings);
                Random random = new Random();
                MexPolicy policy = policies.Values.Where(p => p.Url != null && p.AuthType == userAuthType).OrderBy(p => random.Next()).FirstOrDefault();
                if (policy != null)
                {
                    url = policy.Url;
                }
                else if (userAuthType == UserAuthType.IntegratedAuth)
                {
                    throw new AdalException(AdalError.IntegratedAuthFailed, new AdalException(AdalError.WsTrustEndpointNotFoundInMetadataDocument));
                }
                else
                {
                    throw new AdalException(AdalError.WsTrustEndpointNotFoundInMetadataDocument);
                }
            }
            catch (XmlException ex)
            {
                throw new AdalException(AdalError.ParsingWsMetadataExchangeFailed, ex);
            }

            return url;
        }
        public override string GetRedirectUriAsString(Uri redirectUri, CallState callState)
        {
            string redirectUriString;

            if (ReferenceEquals(redirectUri, Constant.SsoPlaceHolderUri))
            {
                try
                {
                    redirectUriString = WebAuthenticationBroker.GetCurrentApplicationCallbackUri().OriginalString;
                }
                catch (FormatException ex)
                {
                    // This is the workaround for a bug in managed Uri class of WinPhone SDK which makes it throw UriFormatException when it gets called from unmanaged code. 
                    const string CurrentApplicationCallbackUriSetting = "CurrentApplicationCallbackUri";
                    if (ApplicationData.Current.LocalSettings.Values.ContainsKey(CurrentApplicationCallbackUriSetting))
                    {
                        redirectUriString = (string)ApplicationData.Current.LocalSettings.Values[CurrentApplicationCallbackUriSetting];
                    }
                    else
                    {
                        throw new AdalException(AdalErrorEx.NeedToSetCallbackUriAsLocalSetting, AdalErrorMessageEx.NeedToSetCallbackUriAsLocalSetting, ex);
                    }
                }
            }
            else
            {
                redirectUriString = redirectUri.OriginalString;
            }

            return redirectUriString;
        }
 public void BeginClientMetricsRecord(IHttpWebRequest request, CallState callState)
 {
     if (callState != null && callState.AuthorityType == AuthorityType.AAD)
     {
         AddClientMetricsHeadersToRequest(request);
         metricsTimer = Stopwatch.StartNew();
     }            
 }
        public virtual Uri ValidateRedirectUri(Uri redirectUri, CallState callState)
        {
            if (redirectUri == null)
            {
                throw new ArgumentNullException("redirectUri");
            }

            return redirectUri;
        }
 internal static void Error(CallState callState, Exception ex)
 {
     string message = PrepareLogMessage(callState, GetCallerType(), "{0}", ex);
     AdalTrace.TraceSource.TraceEvent(TraceEventType.Error, 4, message);
     if (AdalTrace.LegacyTraceSwitch.TraceError)
     {
         Trace.TraceError(message);
     }
 }
 internal static void Warning(CallState callState, string format, params object[] args)
 {
     string message = PrepareLogMessage(callState, GetCallerType(), format, args);
     AdalTrace.TraceSource.TraceEvent(TraceEventType.Warning, 3, message);
     if (AdalTrace.LegacyTraceSwitch.TraceWarning)
     {
         Trace.TraceWarning(message);
     }
 }
 internal static void Information(CallState callState, string format, params object[] args)
 {
     string message = PrepareLogMessage(callState, GetCallerType(), format, args);
     AdalTrace.TraceSource.TraceData(TraceEventType.Information, 2, message);
     if (AdalTrace.LegacyTraceSwitch.TraceInfo)
     {
         Trace.TraceInformation(message);
     }
 }
        public override Uri ValidateRedirectUri(Uri redirectUri, CallState callState)
        {
            if (redirectUri == null)
            {
                redirectUri = Constant.SsoPlaceHolderUri;
                PlatformPlugin.Logger.Verbose(callState, "ms-app redirect Uri is used");
            }

            return redirectUri;
        }
        internal static async Task<UserRealmDiscoveryResponse> CreateByDiscoveryAsync(string userRealmUri, string userName, CallState callState)
        {
            string userRealmEndpoint = userRealmUri;
            userRealmEndpoint += (userName + "?api-version=1.0");

            PlatformPlugin.Logger.Information(callState, string.Format("Sending user realm discovery request to '{0}'", userRealmEndpoint));

            var client = new AdalHttpClient(userRealmEndpoint, callState) { Client = { Accept = "application/json" } };
            return await client.GetResponseAsync<UserRealmDiscoveryResponse>(ClientMetricsEndpointType.UserRealmDiscovery);
        }
Beispiel #14
0
 public void Authenticate(Uri authorizationUri, Uri redirectUri, CallState callState)
 {
     try
     {
         WebAuthenticationBroker.AuthenticateAndContinue(authorizationUri, ReferenceEquals(redirectUri, Constant.SsoPlaceHolderUri) ? null : redirectUri, null, WebAuthenticationOptions.None);
     }
     catch (Exception ex)
     {
         throw new AdalException(AdalError.AuthenticationUiFailed, ex);
     }
 }
        public override async Task<bool> IsUserLocalAsync(CallState callState)
        {
            WindowsIdentity current = WindowsIdentity.GetCurrent();
            if (current != null)
            {
                string prefix = WindowsIdentity.GetCurrent().Name.Split('\\')[0].ToUpperInvariant();
                return prefix.Equals(Environment.MachineName.ToUpperInvariant());
            }

            return false;
        }
        internal static void Verbose(CallState callState, string format, params object[] args)
        {

            string message = PrepareLogMessage(callState, GetCallerType(), format, args);
            AdalTrace.TraceSource.TraceEvent(TraceEventType.Verbose, 1, message);
            if (AdalTrace.LegacyTraceSwitch.TraceVerbose)
            {
                // There is no TraceVerbose method.
                Trace.TraceInformation(message);
            }
        }
Beispiel #17
0
 public void Authenticate(Uri authorizationUri, Uri redirectUri, CallState callState)
 {
     try
     {
         this.parameters.CallerViewController.PresentViewController(new AuthenticationAgentUINavigationController(authorizationUri.AbsoluteUri, redirectUri.OriginalString, CallbackMethod), false, null);
     }
     catch (Exception ex)
     {
         throw new AdalException(AdalError.AuthenticationUiFailed, ex);
     }
 }
        public async Task VerifyAnotherHostByInstanceDiscoveryAsync(string host, string tenant, CallState callState)
        {
            string instanceDiscoveryEndpoint = this.InstanceDiscoveryEndpoint;
            instanceDiscoveryEndpoint += ("?api-version=1.0&authorization_endpoint=" + AuthorizeEndpointTemplate);
            instanceDiscoveryEndpoint = instanceDiscoveryEndpoint.Replace("{host}", host);
            instanceDiscoveryEndpoint = instanceDiscoveryEndpoint.Replace("{tenant}", tenant);

            instanceDiscoveryEndpoint = HttpHelper.CheckForExtraQueryParameter(instanceDiscoveryEndpoint);

            ClientMetrics clientMetrics = new ClientMetrics();

            try
            {
                IHttpWebRequest request = NetworkPlugin.HttpWebRequestFactory.Create(instanceDiscoveryEndpoint);
                request.Method = "GET";
                HttpHelper.AddCorrelationIdHeadersToRequest(request, callState);
                AdalIdHelper.AddAsHeaders(request);

                clientMetrics.BeginClientMetricsRecord(request, callState);

                using (var response = await request.GetResponseSyncOrAsync(callState))
                {
                    HttpHelper.VerifyCorrelationIdHeaderInReponse(response, callState);
                    InstanceDiscoveryResponse discoveryResponse = HttpHelper.DeserializeResponse<InstanceDiscoveryResponse>(response);
                    clientMetrics.SetLastError(null);
                    if (discoveryResponse.TenantDiscoveryEndpoint == null)
                    {
                        throw new AdalException(AdalError.AuthorityNotInValidList);
                    }
                }
            }
            catch (WebException ex)
            {
                TokenResponse tokenResponse = OAuth2Response.ReadErrorResponse(ex.Response);
                clientMetrics.SetLastError(tokenResponse != null ? tokenResponse.ErrorCodes : null);

                if (tokenResponse.Error == "invalid_instance")
                {
                    throw new AdalServiceException(AdalError.AuthorityNotInValidList, ex);
                }
                else
                {
                    throw new AdalServiceException(
                        AdalError.AuthorityValidationFailed,
                        string.Format(CultureInfo.InvariantCulture, "{0}. {1}: {2}", AdalErrorMessage.AuthorityValidationFailed, tokenResponse.Error, tokenResponse.ErrorDescription),
                        tokenResponse.ErrorCodes,
                        ex);
                }
            }
            finally
            {
                clientMetrics.EndClientMetricsRecord(ClientMetricsEndpointType.InstanceDiscovery, callState);
            }
        }
        public static async Task<WsTrustResponse> SendRequestAsync(WsTrustAddress wsTrustAddress, UserCredential credential, CallState callState)
        {
            IHttpWebRequest request = NetworkPlugin.HttpWebRequestFactory.Create(wsTrustAddress.Uri.AbsoluteUri);
            request.ContentType = "application/soap+xml;";
            if (credential.UserAuthType == UserAuthType.IntegratedAuth)
            {
                SetKerberosOption(request);
            }

            StringBuilder messageBuilder = BuildMessage(DefaultAppliesTo, wsTrustAddress, credential);
            string soapAction = XmlNamespace.Issue.ToString();
            if (wsTrustAddress.Version == WsTrustVersion.WsTrust2005)
            {
                soapAction = XmlNamespace.Issue2005.ToString();
            }

            Dictionary<string, string> headers = new Dictionary<string, string> 
            { 
                { "SOAPAction", soapAction }
            };

            WsTrustResponse wstResponse;

            try
            {
                HttpHelper.SetPostRequest(request, new RequestParameters(messageBuilder), callState, headers);
                IHttpWebResponse response = await request.GetResponseSyncOrAsync(callState);
                wstResponse = WsTrustResponse.CreateFromResponse(response.GetResponseStream(), wsTrustAddress.Version);
            }
            catch (WebException ex)
            {
                string errorMessage;

                try
                {
                    XDocument responseDocument = WsTrustResponse.ReadDocumentFromResponse(ex.Response.GetResponseStream());
                    errorMessage = WsTrustResponse.ReadErrorResponse(responseDocument, callState);
                }
                catch (AdalException)
                {
                    errorMessage = "See inner exception for detail.";
                }

                throw new AdalServiceException(
                    AdalError.FederatedServiceReturnedError,
                    string.Format(AdalErrorMessage.FederatedServiceReturnedErrorTemplate, wsTrustAddress.Uri, errorMessage),
                    null,
                    ex);
            }

            return wstResponse;
        }
Beispiel #20
0
 public void Authenticate(Uri authorizationUri, Uri redirectUri, CallState callState)
 {
     try
     {
         var agentIntent = new Intent(this.parameters.CallerActivity, typeof(AuthenticationAgentActivity));
         agentIntent.PutExtra("Url", authorizationUri.AbsoluteUri);
         agentIntent.PutExtra("Callback", redirectUri.OriginalString);
         this.parameters.CallerActivity.StartActivityForResult(agentIntent, 0);
     }
     catch (Exception ex)
     {
         throw new AdalException(AdalError.AuthenticationUiFailed, ex);
     }
 }
        public Dictionary<string, string> GetPreviousRequestRecord(CallState callState)
        {
            Dictionary<string, string> parameters;
            if (callState != null && callState.AuthorityType == AuthorityType.AAD)
            {
                parameters = GetClientMetricsParameters();
            }
            else
            {
                parameters = new Dictionary<string, string>();
            }

            return parameters;
        }
        public override async Task <bool> IsUserLocalAsync(CallState callState)
        {
            return(await Task.Factory.StartNew(() =>
            {
                WindowsIdentity current = WindowsIdentity.GetCurrent();
                if (current != null)
                {
                    string prefix = WindowsIdentity.GetCurrent().Name.Split('\\')[0].ToUpperInvariant();
                    return prefix.Equals(Environment.MachineName.ToUpperInvariant());
                }

                return false;
            }).ConfigureAwait(false));
        }
Beispiel #23
0
        public async Task <IHttpWebResponse> GetResponseSyncOrAsync(CallState callState)
        {
            if (this.BodyParameters != null)
            {
                using (Stream stream = await GetRequestStreamSyncOrAsync(callState))
                {
                    this.BodyParameters.WriteToStream(stream);
                }
            }

#if ADAL_NET
            if (callState != null && callState.CallSync)
            {
                this.request.Timeout = this.timeoutInMilliSeconds;
                return(NetworkPlugin.HttpWebRequestFactory.CreateResponse(this.request.GetResponse()));
            }

            Task <WebResponse> getResponseTask = this.request.GetResponseAsync();
            System.Threading.ThreadPool.RegisterWaitForSingleObject(
                ((IAsyncResult)getResponseTask).AsyncWaitHandle,
                delegate(object state, bool timedOut)
            {
                if (timedOut)
                {
                    ((HttpWebRequest)state).Abort();
                }
            },
                this.request,
                this.timeoutInMilliSeconds,
                true);

            return(NetworkPlugin.HttpWebRequestFactory.CreateResponse(await getResponseTask));
#else
            var timer = Windows.System.Threading.ThreadPoolTimer.CreateTimer(
                delegate
            {
                this.request.Abort();
            },
                TimeSpan.FromMilliseconds(this.timeoutInMilliSeconds));

            try
            {
                return(NetworkPlugin.HttpWebRequestFactory.CreateResponse(await this.request.GetResponseAsync()));
            }
            finally
            {
                timer.Cancel();
            }
#endif
        }
        internal override void Warning(CallState callState, string message, [System.Runtime.CompilerServices.CallerFilePath] string callerFilePath = "")
        {
            string log = PrepareLogMessage(callState, GetCallerFilename(callerFilePath), message);

            if (LoggerCallbackHandler.UseDefaultLogging)
            {
#if NETSTANDARD1_3
                Console.WriteLine(log);
#else
                AdalEventSource.Warning(log);
#endif
            }

            LoggerCallbackHandler.ExecuteCallback(LogLevel.Warning, log);
        }
        public Dictionary <string, string> GetPreviousRequestRecord(CallState callState)
        {
            Dictionary <string, string> parameters;

            if (callState != null && callState.AuthorityType == AuthorityType.AAD)
            {
                parameters = GetClientMetricsParameters();
            }
            else
            {
                parameters = new Dictionary <string, string>();
            }

            return(parameters);
        }
        public static void AddCorrelationIdHeadersToRequest(IHttpWebRequest request, CallState callState)
        {
            if (callState == null || callState.CorrelationId == Guid.Empty)
            {
                return;
            }

            Dictionary <string, string> headers = new Dictionary <string, string>
            {
                { OAuthHeader.CorrelationId, callState.CorrelationId.ToString() },
                { OAuthHeader.RequestCorrelationIdInResponse, "true" }
            };

            AddHeadersToRequest(request, headers);
        }
Beispiel #27
0
 public void Authenticate(Uri authorizationUri, Uri redirectUri, CallState callState)
 {
     try
     {
         var agentIntent = new Intent(this.parameters.CallerActivity, typeof(AuthenticationAgentActivity));
         agentIntent.PutExtra("Url", authorizationUri.AbsoluteUri);
         agentIntent.PutExtra("Callback", redirectUri.AbsoluteUri);
         this.parameters.CallerActivity.StartActivityForResult(agentIntent, 0);
     }
     catch (Exception ex)
     {
         var adalEx = new AdalException(AdalError.AuthenticationUiFailed, ex);
         PlatformPlugin.Logger.LogException(callState, ex);
         throw adalEx;
     }
 }
 public void Authenticate(Uri authorizationUri, Uri redirectUri, CallState callState)
 {
     try
     {
         this.parameters.CallerViewController.InvokeOnMainThread(() =>
         {
             var navigationController =
                 new AuthenticationAgentUINavigationController(authorizationUri.AbsoluteUri,
                                                               redirectUri.OriginalString, CallbackMethod);
             this.parameters.CallerViewController.PresentViewController(navigationController, false, null);
         });
     }
     catch (Exception ex)
     {
         throw new AdalException(AdalError.AuthenticationUiFailed, ex);
     }
 }
 // This constructor is called by ContinueAcquireTokenAsync after WAB call has returned.
 public AcquireTokenInteractiveHandler(Authenticator authenticator, TokenCache tokenCache, IWebAuthenticationBrokerContinuationEventArgs args)
     : this(
         authenticator, 
         tokenCache, 
         (string)args.ContinuationData[WabArgName.Resource], 
         (string)args.ContinuationData[WabArgName.ClientId],
         GetRedirectUri((string)args.ContinuationData[WabArgName.RedirectUri]),	// Issue #129 - Windows Phone cannot handle ms-app URI's so use the placeholder URI for SSO
         PromptBehavior.Always,  // This is simply to disable cache lookup. In fact, there is no authorize call at this point and promptBehavior is not applicable.
         new UserIdentifier((string)args.ContinuationData[WabArgName.UserId],
             (UserIdentifierType)((int)args.ContinuationData[WabArgName.UserIdType])),
         null, 
         NetworkPlugin.WebUIFactory.Create(), 
         false)
 {
     CallState callState = new CallState(new Guid((string)args.ContinuationData[WabArgName.CorrelationId]), false);
     this.authorizationResult = this.webUi.ProcessAuthorizationResult(args, callState);
 }
Beispiel #30
0
        public async Task<AuthorizationResult> AcquireAuthorizationAsync(Uri authorizationUri, Uri redirectUri, CallState callState)
        {
            bool ssoMode = ReferenceEquals(redirectUri, Constant.SsoPlaceHolderUri);
            if (this.promptBehavior == PromptBehavior.Never && !ssoMode && redirectUri.Scheme != Constant.MsAppScheme)
            {
                throw new ArgumentException(AdalErrorMessageEx.RedirectUriUnsupportedWithPromptBehaviorNever, "redirectUri");
            }
            
            WebAuthenticationResult webAuthenticationResult;

            WebAuthenticationOptions options = (this.useCorporateNetwork && (ssoMode || redirectUri.Scheme == Constant.MsAppScheme)) ? WebAuthenticationOptions.UseCorporateNetwork : WebAuthenticationOptions.None;

            if (this.promptBehavior == PromptBehavior.Never)
            {
                options |= WebAuthenticationOptions.SilentMode;
            }

            try
            {
                if (ssoMode)
                {
                    webAuthenticationResult = await WebAuthenticationBroker.AuthenticateAsync(options, authorizationUri);
                }
                else
                { 
                    webAuthenticationResult = await WebAuthenticationBroker.AuthenticateAsync(options, authorizationUri, redirectUri);
                }
            }
            catch (FileNotFoundException ex)
            {
                throw new AdalException(AdalError.AuthenticationUiFailed, ex);
            }
            catch (Exception ex)
            {
                if (this.promptBehavior == PromptBehavior.Never)
                {
                    throw new AdalException(AdalError.UserInteractionRequired, ex);
                }

                throw new AdalException(AdalError.AuthenticationUiFailed, ex);
            }

            AuthorizationResult result = ProcessAuthorizationResult(webAuthenticationResult, callState);

            return result;
        }
        public void Authenticate(Uri authorizationUri, Uri redirectUri, IDictionary<string, object> headersMap, CallState callState)
        {
            ValueSet set = new ValueSet();
            foreach (string key in headersMap.Keys)
            {
                set[key] = headersMap[key];
            }

            try
            {
                WebAuthenticationBroker.AuthenticateAndContinue(authorizationUri, ReferenceEquals(redirectUri, Constant.SsoPlaceHolderUri) ? null : redirectUri, set, WebAuthenticationOptions.None);
            }
            catch (Exception ex)
            {
                throw new AdalException(AdalError.AuthenticationUiFailed, ex);
            }
        }
 public void EndClientMetricsRecord(string endpoint, CallState callState)
 {
     if (callState != null && callState.AuthorityType == AuthorityType.AAD && metricsTimer != null)
     {
         metricsTimer.Stop();
         lastResponseTime = metricsTimer.ElapsedMilliseconds;
         lastCorrelationId = callState.CorrelationId;
         lastEndpoint = endpoint;
         lock (PendingClientMetricsLock)
         {
             if (pendingClientMetrics == null)
             {
                 pendingClientMetrics = this;
             }
         }
     }
 }
 public void EndClientMetricsRecord(string endpoint, CallState callState)
 {
     if (callState != null && callState.AuthorityType == AuthorityType.AAD && metricsTimer != null)
     {
         metricsTimer.Stop();
         lastResponseTime  = metricsTimer.ElapsedMilliseconds;
         lastCorrelationId = callState.CorrelationId;
         lastEndpoint      = endpoint;
         lock (PendingClientMetricsLock)
         {
             if (pendingClientMetrics == null)
             {
                 pendingClientMetrics = this;
             }
         }
     }
 }
        internal static WsTrustAddress ExtractWsTrustAddressFromMex(XDocument mexDocument, UserAuthType userAuthType,
                                                                    CallState callState)
        {
            WsTrustAddress address = null;
            MexPolicy      policy  = null;

            try
            {
                Dictionary <string, MexPolicy> policies = ReadPolicies(mexDocument);
                Dictionary <string, MexPolicy> bindings = ReadPolicyBindings(mexDocument, policies);
                SetPolicyEndpointAddresses(mexDocument, bindings);
                Random random = new Random();
                //try ws-trust 1.3 first
                policy =
                    policies.Values.Where(
                        p => p.Url != null && p.AuthType == userAuthType && p.Version == WsTrustVersion.WsTrust13)
                    .OrderBy(p => random.Next())
                    .FirstOrDefault() ??
                    policies.Values.Where(p => p.Url != null && p.AuthType == userAuthType)
                    .OrderBy(p => random.Next())
                    .FirstOrDefault();

                if (policy != null)
                {
                    address         = new WsTrustAddress();
                    address.Uri     = policy.Url;
                    address.Version = policy.Version;
                }
                else if (userAuthType == UserAuthType.IntegratedAuth)
                {
                    throw new AdalException(AdalError.IntegratedAuthFailed,
                                            new AdalException(AdalError.WsTrustEndpointNotFoundInMetadataDocument));
                }
                else
                {
                    throw new AdalException(AdalError.WsTrustEndpointNotFoundInMetadataDocument);
                }
            }
            catch (XmlException ex)
            {
                throw new AdalException(AdalError.ParsingWsMetadataExchangeFailed, ex);
            }

            return(address);
        }
Beispiel #35
0
        /// <summary>
        /// Parse a delimited string of key-value pairs in to a dictionary.
        /// </summary>
        /// <param name="input">Delimited string of key-value pairs</param>
        /// <param name="delimiter">Character used as a delimiter between key-value pairs</param>
        /// <param name="urlDecode">True to perform URL decoding of both the keys and values</param>
        /// <param name="lowercaseKeys">True to make all resulting keys lower-case</param>
        /// <param name="strict">Throw <see cref="ArgumentException"/> when the input string contains a malformed key-value pair</param>
        /// <exception cref="ArgumentException">Thrown if <paramref name="strict"/> is true and a malformed key-value pair is present in <paramref name="input"/></exception>
        /// <returns>Dictionary of string key-value pairs</returns>
        private static Dictionary <string, string> ParseKeyValueList(string input, char delimiter, bool urlDecode, bool lowercaseKeys,
                                                                     CallState callState, bool strict)
        {
            var response = new Dictionary <string, string>();

            List <string> queryPairs = SplitWithQuotes(input, delimiter);

            foreach (string queryPair in queryPairs)
            {
                List <string> pair = SplitWithQuotes(queryPair, '=');

                if (pair.Count == 2 && !string.IsNullOrWhiteSpace(pair[0]) && !string.IsNullOrWhiteSpace(pair[1]))
                {
                    string key   = pair[0];
                    string value = pair[1];

                    // Url decoding is needed for parsing OAuth response, but not for parsing WWW-Authenticate header in 401 challenge
                    if (urlDecode)
                    {
                        key   = UrlDecode(key);
                        value = UrlDecode(value);
                    }

                    if (lowercaseKeys)
                    {
                        key = key.Trim().ToLowerInvariant();
                    }

                    value = value.Trim().Trim(new[] { '\"' }).Trim();

                    if (response.ContainsKey(key) && callState != null)
                    {
                        PlatformPlugin.Logger.Warning(callState, string.Format(CultureInfo.CurrentCulture, "Key/value pair list contains redundant key '{0}'.", key));
                    }

                    response[key] = value;
                }
                else if (strict && pair.Count > 2)
                {
                    throw new ArgumentException(nameof(input));
                }
            }

            return(response);
        }
        public async Task <IHttpWebResponse> GetResponseSyncOrAsync(CallState callState)
        {
            if (this.BodyParameters != null)
            {
                using (Stream stream = await GetRequestStreamSyncOrAsync(callState))
                {
                    this.BodyParameters.WriteToStream(stream);
                }
            }

#if ADAL_NET
            if (callState != null && callState.CallSync)
            {
                return(NetworkPlugin.HttpWebRequestFactory.CreateResponse(this.request.GetResponse()));
            }
#endif
            return(NetworkPlugin.HttpWebRequestFactory.CreateResponse(await this.request.GetResponseAsync()));
        }
Beispiel #37
0
        // This constructor is called by ContinueAcquireTokenAsync after WAB call has returned.
        public AcquireTokenInteractiveHandler(Authenticator authenticator, TokenCache tokenCache, IWebAuthenticationBrokerContinuationEventArgs args)
            : this(
                authenticator,
                tokenCache,
                (string)args.ContinuationData[WabArgName.Resource],
                (string)args.ContinuationData[WabArgName.ClientId],
                new Uri((string)args.ContinuationData[WabArgName.RedirectUri]),
                PromptBehavior.Always,  // This is simply to disable cache lookup. In fact, there is no authorize call at this point and promptBehavior is not applicable.
                new UserIdentifier((string)args.ContinuationData[WabArgName.UserId],
                                   (UserIdentifierType)((int)args.ContinuationData[WabArgName.UserIdType])),
                null,
                NetworkPlugin.WebUIFactory.Create(),
                false)
        {
            CallState callState = new CallState(new Guid((string)args.ContinuationData[WabArgName.CorrelationId]), false);

            this.authorizationResult = this.webUi.ProcessAuthorizationResult(args, callState);
        }
Beispiel #38
0
        private static async Task <AuthenticationParameters> CreateFromResourceUrlCommonAsync(Uri resourceUrl)
        {
            CallState callState = new CallState(Guid.NewGuid(), false);

            if (resourceUrl == null)
            {
                throw new ArgumentNullException("resourceUrl");
            }

            IHttpWebResponse         response = null;
            AuthenticationParameters authParams;

            try
            {
                IHttpWebRequest request = NetworkPlugin.HttpWebRequestFactory.Create(resourceUrl.AbsoluteUri);
                request.ContentType = "application/x-www-form-urlencoded";
                response            = await request.GetResponseSyncOrAsync(callState);

                var ex = new AdalException(AdalError.UnauthorizedResponseExpected);
                Logger.Error(null, ex);
                throw ex;
            }
            catch (WebException ex)
            {
                response = NetworkPlugin.HttpWebRequestFactory.CreateResponse(ex.Response);
                if (response == null)
                {
                    var serviceEx = new AdalServiceException(AdalErrorMessage.UnauthorizedHttpStatusCodeExpected, ex);
                    Logger.Error(null, serviceEx);
                    throw serviceEx;
                }

                authParams = CreateFromUnauthorizedResponseCommon(response);
            }
            finally
            {
                if (response != null)
                {
                    response.Close();
                }
            }

            return(authParams);
        }
        public AcquireTokenInteractiveHandler(Authenticator authenticator, TokenCache tokenCache, AuthenticationContextDelegate authenticationContextDelegate, IWebAuthenticationBrokerContinuationEventArgs args)
            : this(
                authenticator,
                tokenCache,
                (string)args.ContinuationData[WabArgName.Resource],
                (string)args.ContinuationData[WabArgName.ClientId],
                new Uri((string)args.ContinuationData[WabArgName.RedirectUri]),
                PromptBehavior.RefreshSession,
                new UserIdentifier((string)args.ContinuationData[WabArgName.UserId],
                                   (UserIdentifierType)((int)args.ContinuationData[WabArgName.UserIdType])),
                null,
                NetworkPlugin.WebUIFactory.Create(),
                false)
        {
            CallState callState = new CallState(new Guid((string)args.ContinuationData[WabArgName.CorrelationId]), false);

            this.authorizationResult           = this.webUi.ProcessAuthorizationResult(args, callState);
            this.authenticationContextDelegate = authenticationContextDelegate;
        }
        public async Task UpdateFromTemplateAsync(CallState callState)
        {
            if (!this.updatedFromTemplate)
            {
                var authorityUri = new Uri(this.Authority);
                string host = authorityUri.Authority;
                string path = authorityUri.AbsolutePath.Substring(1);
                string tenant = path.Substring(0, path.IndexOf("/", StringComparison.Ordinal));

                AuthenticatorTemplate matchingTemplate = await AuthenticatorTemplateList.FindMatchingItemAsync(this.ValidateAuthority, host, tenant, callState);

                this.AuthorizationUri = matchingTemplate.AuthorizeEndpoint.Replace("{tenant}", tenant);
                this.TokenUri = matchingTemplate.TokenEndpoint.Replace("{tenant}", tenant);
                this.UserRealmUri = CanonicalizeUri(matchingTemplate.UserRealmEndpoint);
                this.IsTenantless = (string.Compare(tenant, TenantlessTenantName, StringComparison.OrdinalIgnoreCase) == 0);
                this.SelfSignedJwtAudience = matchingTemplate.Issuer.Replace("{tenant}", tenant);
                this.updatedFromTemplate = true;
            }
        }
        public static async Task<WsTrustResponse> SendRequestAsync(Uri url, UserCredential credential, CallState callState)
        {
            IHttpClient request = PlatformPlugin.HttpClientFactory.Create(url.AbsoluteUri, callState);
            request.ContentType = "application/soap+xml";
            if (credential.UserAuthType == UserAuthType.IntegratedAuth)
            {
                SetKerberosOption(request);
            }

            StringBuilder messageBuilder = BuildMessage(DefaultAppliesTo, url.AbsoluteUri, credential);
            request.Headers["SOAPAction"] = XmlNamespace.Issue.ToString();

            WsTrustResponse wstResponse;

            try
            {
                request.BodyParameters = new StringRequestParameters(messageBuilder);
                IHttpWebResponse response = await request.GetResponseAsync();
                wstResponse = WsTrustResponse.CreateFromResponse(response.ResponseStream);
            }
            catch (HttpRequestWrapperException ex)
            {
                string errorMessage;

                try
                {
                    XDocument responseDocument = WsTrustResponse.ReadDocumentFromResponse(ex.WebResponse.ResponseStream);
                    errorMessage = WsTrustResponse.ReadErrorResponse(responseDocument, callState);
                }
                catch (AdalException)
                {
                    errorMessage = "See inner exception for detail.";
                }

                throw new AdalServiceException(
                    AdalError.FederatedServiceReturnedError,
                    string.Format(AdalErrorMessage.FederatedServiceReturnedErrorTemplate, url, errorMessage),
                    null,
                    ex);
            }

            return wstResponse;
        }
        public async Task UpdateFromTemplateAsync(CallState callState)
        {
            if (!this.updatedFromTemplate)
            {
                var    authorityUri = new Uri(this.Authority);
                string host         = authorityUri.Authority;
                string path         = authorityUri.AbsolutePath.Substring(1);
                string tenant       = path.Substring(0, path.IndexOf("/", StringComparison.Ordinal));

                AuthenticatorTemplate matchingTemplate = await AuthenticatorTemplateList.FindMatchingItemAsync(this.ValidateAuthority, host, tenant, callState);

                this.AuthorizationUri      = matchingTemplate.AuthorizeEndpoint.Replace("{tenant}", tenant);
                this.TokenUri              = matchingTemplate.TokenEndpoint.Replace("{tenant}", tenant);
                this.UserRealmUri          = CanonicalizeUri(matchingTemplate.UserRealmEndpoint);
                this.IsTenantless          = (string.Compare(tenant, TenantlessTenantName, StringComparison.OrdinalIgnoreCase) == 0);
                this.SelfSignedJwtAudience = matchingTemplate.Issuer.Replace("{tenant}", tenant);
                this.updatedFromTemplate   = true;
            }
        }
        internal static async Task<UserRealmDiscoveryResponse> CreateByDiscoveryAsync(string userRealmUri, string userName, CallState callState)
        {
            string userRealmEndpoint = userRealmUri;
            userRealmEndpoint += (userName + "?api-version=1.0");

            userRealmEndpoint = HttpHelper.CheckForExtraQueryParameter(userRealmEndpoint);
            Logger.Information(callState, "Sending user realm discovery request to '{0}'", userRealmEndpoint);

            UserRealmDiscoveryResponse userRealmResponse;
            ClientMetrics clientMetrics = new ClientMetrics();

            try
            {
                IHttpWebRequest request = NetworkPlugin.HttpWebRequestFactory.Create(userRealmEndpoint);
                request.Method = "GET";
                request.Accept = "application/json";
                HttpHelper.AddCorrelationIdHeadersToRequest(request, callState);
                AdalIdHelper.AddAsHeaders(request);

                clientMetrics.BeginClientMetricsRecord(request, callState);

                using (var response = await request.GetResponseSyncOrAsync(callState))
                {
                    HttpHelper.VerifyCorrelationIdHeaderInReponse(response, callState);
                    userRealmResponse = HttpHelper.DeserializeResponse<UserRealmDiscoveryResponse>(response);
                    clientMetrics.SetLastError(null);
                }
            }
            catch (WebException ex)
            {
                var serviceException = new AdalServiceException(AdalError.UserRealmDiscoveryFailed, ex);
                clientMetrics.SetLastError(new[] { serviceException.StatusCode.ToString() });
                throw serviceException;
            }
            finally
            {
                clientMetrics.EndClientMetricsRecord(ClientMetricsEndpointType.UserRealmDiscovery, callState);
            }

            return userRealmResponse;
        }
        private static AuthorizationResult ProcessAuthorizationResult(WebAuthenticationResult webAuthenticationResult, CallState callState)
        {
            AuthorizationResult result;
            switch (webAuthenticationResult.ResponseStatus)
            {
                case WebAuthenticationStatus.Success:
                    result = OAuth2Response.ParseAuthorizeResponse(webAuthenticationResult.ResponseData, callState);
                    break;
                case WebAuthenticationStatus.ErrorHttp:
                    result = new AuthorizationResult(AdalError.AuthenticationFailed, webAuthenticationResult.ResponseErrorDetail.ToString());
                    break;
                case WebAuthenticationStatus.UserCancel:
                    result = new AuthorizationResult(AdalError.AuthenticationCanceled, AdalErrorMessage.AuthenticationCanceled);
                    break;
                default:
                    result = new AuthorizationResult(AdalError.AuthenticationFailed, AdalErrorMessage.AuthorizationServerInvalidResponse);
                    break;
            }

            return result;
        }
        public async Task<AuthorizationResult> AuthenticateAsync(Uri authorizationUri, Uri redirectUri, CallState callState)
        {
            string key = authorizationUri.AbsoluteUri + redirectUri.AbsoluteUri;

            if (IOMap.ContainsKey(key))
            {
                string value = IOMap[key];
                if (value[0] == 'P')
                {
                    return OAuth2Response.ParseAuthorizeResponse(value.Substring(1), callState);
                }
                
                if (value[0] == 'A')
                {
                    string []segments = value.Substring(1).Split(new [] { Delimiter }, StringSplitOptions.RemoveEmptyEntries);
                    return new AuthorizationResult(error: segments[0], errorDescription: segments[1]);
                }
            }

            return null;
        }
        public static string ReadErrorResponse(XDocument responseDocument, CallState callState)
        {
            string errorMessage = null;

            try
            {
                XElement body = responseDocument.Descendants(XmlNamespace.SoapEnvelope + "Body").FirstOrDefault();

                if (body != null)
                {
                    XElement fault = body.Elements(XmlNamespace.SoapEnvelope + "Fault").FirstOrDefault();
                    if (fault != null)
                    {
                        XElement reason = fault.Elements(XmlNamespace.SoapEnvelope + "Reason").FirstOrDefault();
                        if (reason != null)
                        {
                            XElement text = reason.Elements(XmlNamespace.SoapEnvelope + "Text").FirstOrDefault();
                            if (text != null)
                            {
                                using (var reader = text.CreateReader())
                                {
                                    reader.MoveToContent();
                                    errorMessage = reader.ReadInnerXml();
                                }
                            }
                        }
                    }
                }
            }
            catch (XmlException ex)
            {
                var adalEx = new AdalException(AdalError.ParsingWsTrustResponseFailed, ex);
                PlatformPlugin.Logger.LogException(callState, adalEx);
                throw adalEx;
            }

            return(errorMessage);
        }
Beispiel #47
0
        public override async Task <bool> IsUserLocalAsync(CallState callState)
        {
            if (!UserInformation.NameAccessAllowed)
            {
                // The access is not allowed and we cannot determine whether this is a local user or not. So, we do NOT add form auth parameter.
                // This is the case where we can advise customers to add extra query parameter if they want.

                PlatformPlugin.Logger.Information(callState, "Cannot access user information to determine whether it is a local user or not due to machine's privacy setting.");
                return(false);
            }

            try
            {
                return(string.IsNullOrEmpty(await UserInformation.GetDomainNameAsync()));
            }
            catch (UnauthorizedAccessException)
            {
                PlatformPlugin.Logger.Information(callState, "Cannot try Windows Integrated Auth due to lack of Enterprise capability.");
                // This mostly means Enterprise capability is missing, so WIA cannot be used and
                // we return true to add form auth parameter in the caller.
                return(true);
            }
        }
        public void Authenticate(Uri authorizationUri, Uri redirectUri, CallState callState)
        {
            try
            {
                this.parameters.CallerViewController.InvokeOnMainThread(() =>
                {
                    var navigationController =
                        new AuthenticationAgentUINavigationController(authorizationUri.AbsoluteUri,
                                                                      redirectUri.OriginalString, CallbackMethod, this.parameters.PreferredStatusBarStyle);

                    navigationController.ModalPresentationStyle = this.parameters.ModalPresentationStyle;
                    navigationController.ModalTransitionStyle   = this.parameters.ModalTransitionStyle;
                    navigationController.TransitioningDelegate  = this.parameters.TransitioningDelegate;

                    this.parameters.CallerViewController.PresentViewController(navigationController, true, null);
                });
            }
            catch (Exception ex)
            {
                this.parameters = null;
                throw new AdalException(AdalError.AuthenticationUiFailed, ex);
            }
        }
Beispiel #49
0
        public static string ReadErrorResponse(XDocument responseDocument, CallState callState)
        {
            string errorMessage = null;

            try
            {
                XElement body = responseDocument.Descendants(XmlNamespace.SoapEnvelope + "Body").FirstOrDefault();

                if (body != null)
                {
                    XElement fault = body.Elements(XmlNamespace.SoapEnvelope + "Fault").FirstOrDefault();
                    if (fault != null)
                    {
                        errorMessage = GetFaultMessage(fault);
                    }
                }
            }
            catch (XmlException ex)
            {
                throw new AdalException(AdalError.ParsingWsTrustResponseFailed, ex);
            }

            return(errorMessage);
        }
Beispiel #50
0
        public async Task <AuthorizationResult> AcquireAuthorizationAsync(Uri authorizationUri, Uri redirectUri, CallState callState)
        {
            bool ssoMode = ReferenceEquals(redirectUri, Constant.SsoPlaceHolderUri);

            if (this.promptBehavior == PromptBehavior.Never && !ssoMode && redirectUri.Scheme != Constant.MsAppScheme)
            {
                throw new ArgumentException(AdalErrorMessageEx.RedirectUriUnsupportedWithPromptBehaviorNever, "redirectUri");
            }

            WebAuthenticationResult webAuthenticationResult;

            WebAuthenticationOptions options = (this.useCorporateNetwork && (ssoMode || redirectUri.Scheme == Constant.MsAppScheme)) ? WebAuthenticationOptions.UseCorporateNetwork : WebAuthenticationOptions.None;

            if (this.promptBehavior == PromptBehavior.Never)
            {
                options |= WebAuthenticationOptions.SilentMode;
            }

            try
            {
                if (ssoMode)
                {
                    webAuthenticationResult = await WebAuthenticationBroker.AuthenticateAsync(options, authorizationUri);
                }
                else
                {
                    webAuthenticationResult = await WebAuthenticationBroker.AuthenticateAsync(options, authorizationUri, redirectUri);
                }
            }
            catch (FileNotFoundException ex)
            {
                throw new AdalException(AdalError.AuthenticationUiFailed, ex);
            }
            catch (Exception ex)
            {
                if (this.promptBehavior == PromptBehavior.Never)
                {
                    throw new AdalException(AdalError.UserInteractionRequired, ex);
                }

                throw new AdalException(AdalError.AuthenticationUiFailed, ex);
            }

            AuthorizationResult result = ProcessAuthorizationResult(webAuthenticationResult, callState);

            return(result);
        }
Beispiel #51
0
        public async Task <AuthorizationResult> AcquireAuthorizationAsync(Uri authorizationUri, Uri redirectUri, CallState callState)
        {
            returnedUriReady = new SemaphoreSlim(0);
            Authenticate(authorizationUri, redirectUri, callState);
            await returnedUriReady.WaitAsync();

            return(authorizationResult);
        }
 private static void Warning(CallState callState, string callerFilePath, string format, params object[] args)
 {
     AdalEventSource.Warning(PrepareLogMessage(callState, GetCallerFilename(callerFilePath), format, args));
 }
Beispiel #53
0
        internal void StoreToCache(AuthenticationResultEx result, string authority, string resource, string clientId, TokenSubjectType subjectType, CallState callState)
        {
            lock (cacheLock)
            {
                PlatformPlugin.Logger.Verbose(callState, "Storing token in the cache...");

                string uniqueId      = (result.Result.UserInfo != null) ? result.Result.UserInfo.UniqueId : null;
                string displayableId = (result.Result.UserInfo != null) ? result.Result.UserInfo.DisplayableId : null;

                this.OnBeforeWrite(new TokenCacheNotificationArgs
                {
                    Resource      = resource,
                    ClientId      = clientId,
                    UniqueId      = uniqueId,
                    DisplayableId = displayableId
                });

                TokenCacheKey tokenCacheKey = new TokenCacheKey(authority, resource, clientId, subjectType,
                                                                result.Result.UserInfo);
                this.tokenCacheDictionary[tokenCacheKey] = result;
                PlatformPlugin.Logger.Verbose(callState, "An item was stored in the cache");
                this.UpdateCachedMrrtRefreshTokens(result, clientId, subjectType);

                this.HasStateChanged = true;
            }
        }
        internal static async Task <UserRealmDiscoveryResponse> CreateByDiscoveryAsync(string userRealmUri, string userName, CallState callState)
        {
            string userRealmEndpoint = userRealmUri;

            userRealmEndpoint += (userName + "?api-version=1.0");

            PlatformPlugin.Logger.Information(callState, string.Format(CultureInfo.CurrentCulture, " Sending user realm discovery request to '{0}'", userRealmEndpoint));

            var client = new AdalHttpClient(userRealmEndpoint, callState)
            {
                Client = { Accept = "application/json" }
            };

            return(await client.GetResponseAsync <UserRealmDiscoveryResponse>(ClientMetricsEndpointType.UserRealmDiscovery));
        }
Beispiel #55
0
        public static async Task <WsTrustResponse> SendRequestAsync(Uri url, UserCredential credential, CallState callState)
        {
            IHttpWebRequest request = PlatformPlugin.HttpWebRequestFactory.Create(url.AbsoluteUri);

            request.ContentType = "application/soap+xml; charset=utf-8";
            if (credential.UserAuthType == UserAuthType.IntegratedAuth)
            {
                SetKerberosOption(request);
            }

            StringBuilder messageBuilder        = BuildMessage(DefaultAppliesTo, url.AbsoluteUri, credential);
            Dictionary <string, string> headers = new Dictionary <string, string>
            {
                { "SOAPAction", XmlNamespace.Issue.ToString() }
            };

            WsTrustResponse wstResponse;

            try
            {
                HttpHelper.SetPostRequest(request, new RequestParameters(messageBuilder), callState, headers);
                IHttpWebResponse response = await request.GetResponseSyncOrAsync(callState);

                wstResponse = WsTrustResponse.CreateFromResponse(response.GetResponseStream());
            }
            catch (WebException ex)
            {
                string errorMessage;

                try
                {
                    XDocument responseDocument = WsTrustResponse.ReadDocumentFromResponse(ex.Response.GetResponseStream());
                    errorMessage = WsTrustResponse.ReadErrorResponse(responseDocument, callState);
                }
                catch (AdalException)
                {
                    errorMessage = "See inner exception for detail.";
                }

                throw new AdalServiceException(
                          AdalError.FederatedServiceReturnedError,
                          string.Format(AdalErrorMessage.FederatedServiceReturnedErrorTemplate, url, errorMessage),
                          ex);
            }

            return(wstResponse);
        }
Beispiel #56
0
        private static AuthorizationResult ProcessAuthorizationResult(WebAuthenticationResult webAuthenticationResult, CallState callState)
        {
            AuthorizationResult result;

            switch (webAuthenticationResult.ResponseStatus)
            {
            case WebAuthenticationStatus.Success:
                result = new AuthorizationResult(AuthorizationStatus.Success, webAuthenticationResult.ResponseData);
                break;

            case WebAuthenticationStatus.ErrorHttp:
                result = new AuthorizationResult(AuthorizationStatus.ErrorHttp, webAuthenticationResult.ResponseErrorDetail.ToString(CultureInfo.CurrentCulture));
                break;

            case WebAuthenticationStatus.UserCancel:
                result = new AuthorizationResult(AuthorizationStatus.UserCancel, null);
                break;

            default:
                result = new AuthorizationResult(AuthorizationStatus.UnknownError, null);
                break;
            }

            return(result);
        }
Beispiel #57
0
        internal AuthenticationResultEx LoadFromCache(CacheQueryData cacheQueryData, CallState callState)
        {
            lock (cacheLock)
            {
                PlatformPlugin.Logger.Verbose(callState, "Looking up cache for a token...");

                AuthenticationResultEx resultEx = null;
                KeyValuePair <TokenCacheKey, AuthenticationResultEx>?kvp = this.LoadSingleItemFromCache(cacheQueryData, callState);

                if (kvp.HasValue)
                {
                    TokenCacheKey cacheKey = kvp.Value.Key;
                    resultEx = kvp.Value.Value.Clone();

                    bool tokenNearExpiry = (resultEx.Result.ExpiresOn <=
                                            DateTime.UtcNow + TimeSpan.FromMinutes(ExpirationMarginInMinutes));
                    bool tokenExtendedLifeTimeExpired = (resultEx.Result.ExtendedExpiresOn <=
                                                         DateTime.UtcNow);

                    //check for cross-tenant authority
                    if (!cacheKey.Authority.Equals(cacheQueryData.Authority))
                    {
                        // this is a cross-tenant result. use RT only
                        resultEx.Result.AccessToken = null;
                        PlatformPlugin.Logger.Information(callState,
                                                          "Cross Tenant refresh token was found in the cache");
                    }
                    else if (tokenNearExpiry && !cacheQueryData.ExtendedLifeTimeEnabled)
                    {
                        resultEx.Result.AccessToken = null;
                        PlatformPlugin.Logger.Information(callState,
                                                          "An expired or near expiry token was found in the cache");
                    }
                    else if (!cacheKey.ResourceEquals(cacheQueryData.Resource))
                    {
                        PlatformPlugin.Logger.Information(callState,
                                                          string.Format(CultureInfo.CurrentCulture,
                                                                        "Multi resource refresh token for resource '{0}' will be used to acquire token for '{1}'",
                                                                        cacheKey.Resource, cacheQueryData.Resource));
                        var newResultEx = new AuthenticationResultEx
                        {
                            Result             = new AuthenticationResult(null, null, DateTimeOffset.MinValue),
                            RefreshToken       = resultEx.RefreshToken,
                            ResourceInResponse = resultEx.ResourceInResponse
                        };

                        newResultEx.Result.UpdateTenantAndUserInfo(resultEx.Result.TenantId, resultEx.Result.IdToken,
                                                                   resultEx.Result.UserInfo);
                        resultEx = newResultEx;
                    }
                    else if (!tokenExtendedLifeTimeExpired && cacheQueryData.ExtendedLifeTimeEnabled && tokenNearExpiry)
                    {
                        resultEx.Result.ExtendedLifeTimeToken = true;
                        resultEx.Result.ExpiresOn             = resultEx.Result.ExtendedExpiresOn;
                        PlatformPlugin.Logger.Information(callState,
                                                          "The extendedLifeTime is enabled and a stale AT with extendedLifeTimeEnabled is returned.");
                    }
                    else if (tokenExtendedLifeTimeExpired)
                    {
                        resultEx.Result.AccessToken = null;
                        PlatformPlugin.Logger.Information(callState,
                                                          "The AT has expired its ExtendedLifeTime");
                    }
                    else
                    {
                        PlatformPlugin.Logger.Information(callState,
                                                          string.Format(CultureInfo.CurrentCulture, "{0} minutes left until token in cache expires",
                                                                        (resultEx.Result.ExpiresOn - DateTime.UtcNow).TotalMinutes));
                    }

                    if (resultEx.Result.AccessToken == null && resultEx.RefreshToken == null)
                    {
                        this.tokenCacheDictionary.Remove(cacheKey);
                        PlatformPlugin.Logger.Information(callState, "An old item was removed from the cache");
                        this.HasStateChanged = true;
                        resultEx             = null;
                    }

                    if (resultEx != null)
                    {
                        PlatformPlugin.Logger.Information(callState,
                                                          "A matching item (access token or refresh token or both) was found in the cache");
                    }
                }
                else
                {
                    PlatformPlugin.Logger.Information(callState, "No matching token was found in the cache");
                }

                return(resultEx);
            }
        }
        public async Task VerifyAnotherHostByInstanceDiscoveryAsync(string host, string tenant, CallState callState)
        {
            string instanceDiscoveryEndpoint = this.InstanceDiscoveryEndpoint;

            instanceDiscoveryEndpoint += ("?api-version=1.0&authorization_endpoint=" + AuthorizeEndpointTemplate);
            instanceDiscoveryEndpoint  = instanceDiscoveryEndpoint.Replace("{host}", host);
            instanceDiscoveryEndpoint  = instanceDiscoveryEndpoint.Replace("{tenant}", tenant);

            try
            {
                var client = new AdalHttpClient(instanceDiscoveryEndpoint, callState);
                InstanceDiscoveryResponse discoveryResponse = await client.GetResponseAsync <InstanceDiscoveryResponse>().ConfigureAwait(false);

                if (discoveryResponse.TenantDiscoveryEndpoint == null)
                {
                    throw new AdalException(AdalError.AuthorityNotInValidList);
                }
            }
            catch (AdalServiceException ex)
            {
                throw new AdalException((ex.ErrorCode == "invalid_instance") ? AdalError.AuthorityNotInValidList : AdalError.AuthorityValidationFailed, ex);
            }
        }
Beispiel #59
0
        private KeyValuePair <TokenCacheKey, AuthenticationResultEx>?LoadSingleItemFromCache(CacheQueryData cacheQueryData, CallState callState)
        {
            lock (cacheLock)
            {
                // First identify all potential tokens.
                List <KeyValuePair <TokenCacheKey, AuthenticationResultEx> > items =
                    this.QueryCache(cacheQueryData.Authority, cacheQueryData.ClientId, cacheQueryData.SubjectType,
                                    cacheQueryData.UniqueId, cacheQueryData.DisplayableId, cacheQueryData.AssertionHash);

                List <KeyValuePair <TokenCacheKey, AuthenticationResultEx> > resourceSpecificItems =
                    items.Where(p => p.Key.ResourceEquals(cacheQueryData.Resource)).ToList();
                int resourceValuesCount = resourceSpecificItems.Count();

                KeyValuePair <TokenCacheKey, AuthenticationResultEx>?returnValue = null;
                switch (resourceValuesCount)
                {
                case 1:
                    PlatformPlugin.Logger.Information(callState,
                                                      "An item matching the requested resource was found in the cache");
                    returnValue = resourceSpecificItems.First();
                    break;

                case 0:
                {
                    // There are no resource specific tokens.  Choose any of the MRRT tokens if there are any.
                    List <KeyValuePair <TokenCacheKey, AuthenticationResultEx> > mrrtItems =
                        items.Where(p => p.Value.IsMultipleResourceRefreshToken).ToList();

                    if (mrrtItems.Any())
                    {
                        returnValue = mrrtItems.First();
                        PlatformPlugin.Logger.Information(callState,
                                                          "A Multi Resource Refresh Token for a different resource was found which can be used");
                    }
                }
                break;

                default:
                    throw new AdalException(AdalError.MultipleTokensMatched);
                }

                // check for tokens issued to same client_id/user_id combination, but any tenant.
                // this check only applies to user tokens. client tokens should be ignored.
                if (returnValue == null && cacheQueryData.SubjectType != TokenSubjectType.Client)
                {
                    List <KeyValuePair <TokenCacheKey, AuthenticationResultEx> > itemsForAllTenants = this.QueryCache(
                        null, cacheQueryData.ClientId, cacheQueryData.SubjectType, cacheQueryData.UniqueId,
                        cacheQueryData.DisplayableId, cacheQueryData.AssertionHash);
                    if (itemsForAllTenants.Count != 0)
                    {
                        returnValue = itemsForAllTenants.First();
                    }

                    // check if the token was issued by AAD
                    if (returnValue != null &&
                        Authenticator.DetectAuthorityType(returnValue.Value.Key.Authority) == AuthorityType.ADFS)
                    {
                        returnValue = null;
                    }
                }

                return(returnValue);
            }
        }
 internal static void Error(CallState callState, Exception ex, [System.Runtime.CompilerServices.CallerFilePath] string callerFilePath = "")
 {
     AdalEventSource.Error(PrepareLogMessage(callState, GetCallerFilename(callerFilePath), "{0}", ex));
 }