Пример #1
0
        private GetTokenOperation CreateOperation(
            VssTraceActivity traceActivity,
            IssuedToken failedToken,
            CancellationToken cancellationToken,
            out GetTokenOperation operationInProgress)
        {
            operationInProgress = null;
            GetTokenOperation operation = null;

            lock (m_thisLock)
            {
                if (m_operations == null)
                {
                    m_operations = new List <GetTokenOperation>();
                }

                // Grab the main operation which is doing the work (if any)
                if (m_operations.Count > 0)
                {
                    operationInProgress = m_operations[0];

                    // Use the existing completion source when creating the new operation
                    operation = new GetTokenOperation(traceActivity, this, failedToken, cancellationToken, operationInProgress.CompletionSource);
                }
                else
                {
                    operation = new GetTokenOperation(traceActivity, this, failedToken, cancellationToken);
                }

                m_operations.Add(operation);
            }

            return(operation);
        }
Пример #2
0
            private static Task <IssuedToken> PostCallback(
                Object state,
                CancellationTokenSource timeoutTokenSource)
            {
                // Make sure that we were not cancelled (timed out) before this callback is invoked.
                using (timeoutTokenSource)
                {
                    timeoutTokenSource.CancelAfter(-1);
                    if (timeoutTokenSource.IsCancellationRequested)
                    {
                        return(Task.FromResult <IssuedToken>(null));
                    }
                }

                GetTokenOperation thisPtr = (GetTokenOperation)state;

                return(thisPtr.Provider.OnGetTokenAsync(thisPtr.FailedToken, thisPtr.CancellationToken));
            }
Пример #3
0
        /// <summary>
        /// Retrieves a token for the credentials.
        /// </summary>
        /// <param name="failedToken">The token which previously failed authentication, if available</param>
        /// <param name="cancellationToken">The <c>CancellationToken</c>that will be assigned to the new task</param>
        /// <returns>A security token for the current credentials</returns>
        public async Task <IssuedToken> GetTokenAsync(
            IssuedToken failedToken,
            CancellationToken cancellationToken)
        {
            IssuedToken      currentToken      = this.CurrentToken;
            VssTraceActivity traceActivity     = VssTraceActivity.Current;
            Stopwatch        aadAuthTokenTimer = Stopwatch.StartNew();

            try
            {
                VssHttpEventSource.Log.AuthenticationStart(traceActivity);

                if (currentToken != null)
                {
                    VssHttpEventSource.Log.IssuedTokenRetrievedFromCache(traceActivity, this, currentToken);
                    return(currentToken);
                }
                else
                {
                    GetTokenOperation operation = null;
                    try
                    {
                        GetTokenOperation operationInProgress;
                        operation = CreateOperation(traceActivity, failedToken, cancellationToken, out operationInProgress);
                        if (operationInProgress == null)
                        {
                            return(await operation.GetTokenAsync(traceActivity).ConfigureAwait(false));
                        }
                        else
                        {
                            return(await operationInProgress.WaitForTokenAsync(traceActivity, cancellationToken).ConfigureAwait(false));
                        }
                    }
                    finally
                    {
                        lock (m_thisLock)
                        {
                            m_operations.Remove(operation);
                        }

                        operation?.Dispose();
                    }
                }
            }
            finally
            {
                VssHttpEventSource.Log.AuthenticationStop(traceActivity);

                aadAuthTokenTimer.Stop();
                TimeSpan getTokenTime = aadAuthTokenTimer.Elapsed;

                if (getTokenTime.TotalSeconds >= c_slowTokenAcquisitionTimeInSeconds)
                {
                    // It may seem strange to pass the string value of TotalSeconds into this method, but testing
                    // showed that ETW is persnickety when you register a method in an EventSource that doesn't
                    // use strings or integers as its parameters. It is easier to simply give the method a string
                    // than figure out to get ETW to reliably accept a double or TimeSpan.
                    VssHttpEventSource.Log.AuthorizationDelayed(getTokenTime.TotalSeconds.ToString());
                }
            }
        }