From c8c09a531115e9b83b6c73214479c2b4c14063ed Mon Sep 17 00:00:00 2001 From: afshins Date: Mon, 15 Sep 2014 12:32:50 -0700 Subject: [PATCH 1/6] Fixing issue #114: Race condition can happen in parallel token requests when sending client metrics --- src/ADAL.Common/ClientMetrics.cs | 31 ++++++++++++------- ...WindowsFormsWebAuthenticationDialogBase.cs | 2 +- .../Test.ADAL.NET.Unit/NonInteractiveTests.cs | 12 ++----- 3 files changed, 22 insertions(+), 23 deletions(-) diff --git a/src/ADAL.Common/ClientMetrics.cs b/src/ADAL.Common/ClientMetrics.cs index 6b2a64b2c..77a6f6162 100644 --- a/src/ADAL.Common/ClientMetrics.cs +++ b/src/ADAL.Common/ClientMetrics.cs @@ -41,6 +41,7 @@ internal class ClientMetrics private const string ClientMetricsHeaderLastEndpoint = "x-client-last-endpoint"; private static ClientMetrics pendingClientMetrics; + private static readonly object PendingClientMetricsLock = new object(); private Stopwatch metricsTimer; private string lastError; @@ -65,9 +66,12 @@ public void EndClientMetricsRecord(string endpoint, CallState callState) lastResponseTime = metricsTimer.ElapsedMilliseconds; lastCorrelationId = callState.CorrelationId; lastEndpoint = endpoint; - if (pendingClientMetrics == null) + lock (PendingClientMetricsLock) { - pendingClientMetrics = this; + if (pendingClientMetrics == null) + { + pendingClientMetrics = this; + } } } } @@ -79,20 +83,23 @@ public void SetLastError(string[] errorCodes) private static void AddClientMetricsHeadersToRequest(IHttpWebRequest request) { - if (pendingClientMetrics != null && NetworkPlugin.RequestCreationHelper.RecordClientMetrics) + lock (PendingClientMetricsLock) { - Dictionary headers = new Dictionary(); - if (pendingClientMetrics.lastError != null) + if (pendingClientMetrics != null && NetworkPlugin.RequestCreationHelper.RecordClientMetrics) { - headers[ClientMetricsHeaderLastError] = pendingClientMetrics.lastError; - } + Dictionary headers = new Dictionary(); + if (pendingClientMetrics.lastError != null) + { + headers[ClientMetricsHeaderLastError] = pendingClientMetrics.lastError; + } - headers[ClientMetricsHeaderLastRequest] = pendingClientMetrics.lastCorrelationId.ToString(); - headers[ClientMetricsHeaderLastResponseTime] = pendingClientMetrics.lastResponseTime.ToString(); - headers[ClientMetricsHeaderLastEndpoint] = pendingClientMetrics.lastEndpoint; + headers[ClientMetricsHeaderLastRequest] = pendingClientMetrics.lastCorrelationId.ToString(); + headers[ClientMetricsHeaderLastResponseTime] = pendingClientMetrics.lastResponseTime.ToString(); + headers[ClientMetricsHeaderLastEndpoint] = pendingClientMetrics.lastEndpoint; - HttpHelper.AddHeadersToRequest(request, headers); - pendingClientMetrics = null; + HttpHelper.AddHeadersToRequest(request, headers); + pendingClientMetrics = null; + } } } } diff --git a/src/ADAL.NET.WindowsForms/WindowsFormsWebAuthenticationDialogBase.cs b/src/ADAL.NET.WindowsForms/WindowsFormsWebAuthenticationDialogBase.cs index b1f02e79e..077b1eba7 100644 --- a/src/ADAL.NET.WindowsForms/WindowsFormsWebAuthenticationDialogBase.cs +++ b/src/ADAL.NET.WindowsForms/WindowsFormsWebAuthenticationDialogBase.cs @@ -303,7 +303,7 @@ protected AdalException CreateExceptionForAuthenticationUiFailed(int statusCode) return new AdalServiceException( AdalError.AuthenticationUiFailed, - string.Format("The browser based authentication dialog failed to complete for an unkown reason. StatusCode: {0}", statusCode)) { StatusCode = statusCode }; + string.Format("The browser based authentication dialog failed to complete for an unknown reason. StatusCode: {0}", statusCode)) { StatusCode = statusCode }; } protected static class DpiHelper diff --git a/tests/Test.ADAL.NET.Unit/NonInteractiveTests.cs b/tests/Test.ADAL.NET.Unit/NonInteractiveTests.cs index 7b0b86b0f..78c0adf38 100644 --- a/tests/Test.ADAL.NET.Unit/NonInteractiveTests.cs +++ b/tests/Test.ADAL.NET.Unit/NonInteractiveTests.cs @@ -65,16 +65,8 @@ public async Task UserRealmDiscoveryTest() Verify.IsNotNull(ex.ErrorCode, AdalError.UnknownUser); } - try - { - await UserRealmDiscoveryResponse.CreateByDiscoveryAsync(context.Authenticator.UserRealmUri, "ab@cd@ef", null); - Verify.Fail("Exception expected"); - } - catch (AdalException ex) - { - Verify.IsNotNull(ex.ErrorCode, AdalError.UserRealmDiscoveryFailed); - Verify.IsNotNull(ex.InnerException); - } + userRealmResponse = await UserRealmDiscoveryResponse.CreateByDiscoveryAsync(context.Authenticator.UserRealmUri, "ab@cd@ef", null); + Verify.AreEqual("Unknown", userRealmResponse.AccountType); try { From e9b8987e82ee98a47737623d064cbb3a217f561a Mon Sep 17 00:00:00 2001 From: afshins Date: Tue, 16 Sep 2014 13:57:03 -0700 Subject: [PATCH 2/6] Making ADAL assemblies CLS compliant --- src/ADAL.Common/CommonAssemblyInfo.cs | 4 ++++ .../SilentWindowsFormsAuthenticationDialog.cs | 2 +- .../WindowsFormsWebAuthenticationDialogBase.cs | 8 ++++---- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/ADAL.Common/CommonAssemblyInfo.cs b/src/ADAL.Common/CommonAssemblyInfo.cs index 3a0a8eb80..0ad578fc1 100644 --- a/src/ADAL.Common/CommonAssemblyInfo.cs +++ b/src/ADAL.Common/CommonAssemblyInfo.cs @@ -16,6 +16,7 @@ // limitations under the License. //---------------------------------------------------------------------- +using System; using System.Reflection; [assembly: AssemblyProduct("Active Directory Authentication Library")] @@ -34,3 +35,6 @@ // On official build, attribute AssemblyInformationalVersionAttribute is added as well // with its value equal to the hash of the last commit to the git branch. // e.g.: [assembly: AssemblyInformationalVersionAttribute("4392c9835a38c27516fc0cd7bad7bccdcaeab161")] + +// Assembly marked as compliant. +[assembly: CLSCompliant(true)] diff --git a/src/ADAL.NET.WindowsForms/SilentWindowsFormsAuthenticationDialog.cs b/src/ADAL.NET.WindowsForms/SilentWindowsFormsAuthenticationDialog.cs index ed58d237b..89bcacfcd 100644 --- a/src/ADAL.NET.WindowsForms/SilentWindowsFormsAuthenticationDialog.cs +++ b/src/ADAL.NET.WindowsForms/SilentWindowsFormsAuthenticationDialog.cs @@ -56,7 +56,7 @@ public string Result { get { - return this.result; + return this.authenticationResult; } } diff --git a/src/ADAL.NET.WindowsForms/WindowsFormsWebAuthenticationDialogBase.cs b/src/ADAL.NET.WindowsForms/WindowsFormsWebAuthenticationDialogBase.cs index 077b1eba7..e792ea812 100644 --- a/src/ADAL.NET.WindowsForms/WindowsFormsWebAuthenticationDialogBase.cs +++ b/src/ADAL.NET.WindowsForms/WindowsFormsWebAuthenticationDialogBase.cs @@ -37,7 +37,7 @@ public abstract class WindowsFormsWebAuthenticationDialogBase : Form private Uri desiredCallbackUri; - protected string result; + protected string authenticationResult; protected IWin32Window ownerWindow; @@ -171,7 +171,7 @@ private bool CheckForClosingUrl(Uri url) { if (url.Authority.Equals(this.desiredCallbackUri.Authority, StringComparison.OrdinalIgnoreCase) && url.AbsolutePath.Equals(this.desiredCallbackUri.AbsolutePath)) { - this.result = url.AbsoluteUri; + this.authenticationResult = url.AbsoluteUri; this.StopWebBrowser(); // in this handler object could be already disposed, so it should be the last method @@ -202,7 +202,7 @@ private void StopWebBrowser() public string AuthenticateAAD(Uri requestUri, Uri callbackUri) { this.desiredCallbackUri = callbackUri; - this.result = null; + this.authenticationResult = null; // The WebBrowser event handlers must not throw exceptions. // If they do then they may be swallowed by the native @@ -214,7 +214,7 @@ public string AuthenticateAAD(Uri requestUri, Uri callbackUri) this.webBrowser.Navigate(requestUri); this.OnAuthenticate(); - return this.result; + return this.authenticationResult; } protected virtual void OnAuthenticate() From 08d3f0f5e8db8e2cac69cbc6204e9801281e0749 Mon Sep 17 00:00:00 2001 From: afshins Date: Tue, 16 Sep 2014 14:26:12 -0700 Subject: [PATCH 3/6] Fixing expired test certificate --- .../Test.ADAL.WinRT.Dashboard.csproj | 4 +++- .../Test.ADAL.WinRT.Dashboard_TemporaryKey.pfx | Bin 0 -> 2512 bytes .../Test.ADAL.WinRT.Manual_TemporaryKey.pfx | Bin 2512 -> 0 bytes 3 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 tests/Test.ADAL.WinRT.Dashboard/Test.ADAL.WinRT.Dashboard_TemporaryKey.pfx delete mode 100644 tests/Test.ADAL.WinRT.Dashboard/Test.ADAL.WinRT.Manual_TemporaryKey.pfx diff --git a/tests/Test.ADAL.WinRT.Dashboard/Test.ADAL.WinRT.Dashboard.csproj b/tests/Test.ADAL.WinRT.Dashboard/Test.ADAL.WinRT.Dashboard.csproj index 4e87db7b1..fd875c8ab 100644 --- a/tests/Test.ADAL.WinRT.Dashboard/Test.ADAL.WinRT.Dashboard.csproj +++ b/tests/Test.ADAL.WinRT.Dashboard/Test.ADAL.WinRT.Dashboard.csproj @@ -12,7 +12,8 @@ en-US 512 {BC8A1FFA-BEE3-4634-8014-F334798102B3};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - Test.ADAL.WinRT.Manual_TemporaryKey.pfx + Test.ADAL.WinRT.Dashboard_TemporaryKey.pfx + 01F5820AC51355DCA53BD7273BF55B039B155610 AnyCPU @@ -56,6 +57,7 @@ Designer + diff --git a/tests/Test.ADAL.WinRT.Dashboard/Test.ADAL.WinRT.Dashboard_TemporaryKey.pfx b/tests/Test.ADAL.WinRT.Dashboard/Test.ADAL.WinRT.Dashboard_TemporaryKey.pfx new file mode 100644 index 0000000000000000000000000000000000000000..d8c5aa4d79392d62e11fff6e1bd22ecf0521a8c9 GIT binary patch literal 2512 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 Date: Tue, 16 Sep 2014 14:51:46 -0700 Subject: [PATCH 4/6] Updating version --- src/ADAL.Common/CommonAssemblyInfo.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ADAL.Common/CommonAssemblyInfo.cs b/src/ADAL.Common/CommonAssemblyInfo.cs index 0ad578fc1..96e84410c 100644 --- a/src/ADAL.Common/CommonAssemblyInfo.cs +++ b/src/ADAL.Common/CommonAssemblyInfo.cs @@ -27,11 +27,11 @@ [assembly: AssemblyCopyright("Copyright (c) Microsoft Open Technologies. All rights reserved.")] [assembly: AssemblyTrademark("")] -[assembly: AssemblyVersion("2.10.0.0")] +[assembly: AssemblyVersion("2.11.0.0")] // Keep major and minor versions in AssemblyFileVersion in sync with AssemblyVersion. // Build and revision numbers are replaced on build machine for official builds. -[assembly: AssemblyFileVersion("2.10.00000.0000")] +[assembly: AssemblyFileVersion("2.11.00000.0000")] // On official build, attribute AssemblyInformationalVersionAttribute is added as well // with its value equal to the hash of the last commit to the git branch. // e.g.: [assembly: AssemblyInformationalVersionAttribute("4392c9835a38c27516fc0cd7bad7bccdcaeab161")] From 06aac59b16dd27fb756b09bc19499cac789ec23d Mon Sep 17 00:00:00 2001 From: afshins Date: Wed, 17 Sep 2014 17:57:15 -0700 Subject: [PATCH 5/6] Adding timeout to http request (sync and async) --- src/ADAL.Common/HttpWebRequestWrapper.cs | 45 +++++++++++- .../Test.ADAL.NET.Unit.csproj | 26 +++++++ tests/Test.ADAL.NET.Unit/UnitTests.cs | 73 +++++++++++++++++++ tests/Test.ADAL.WinRT.Unit/UnitTests.cs | 31 ++++++++ 4 files changed, 174 insertions(+), 1 deletion(-) diff --git a/src/ADAL.Common/HttpWebRequestWrapper.cs b/src/ADAL.Common/HttpWebRequestWrapper.cs index edd58f0f5..eb86236f9 100644 --- a/src/ADAL.Common/HttpWebRequestWrapper.cs +++ b/src/ADAL.Common/HttpWebRequestWrapper.cs @@ -16,6 +16,7 @@ // limitations under the License. //---------------------------------------------------------------------- +using System; using System.IO; using System.Net; using System.Threading.Tasks; @@ -26,6 +27,8 @@ internal class HttpWebRequestWrapper : IHttpWebRequest { private readonly HttpWebRequest request; + private int timeoutInMilliSeconds = 30000; + public HttpWebRequestWrapper(string uri) { this.request = (HttpWebRequest)WebRequest.Create(uri); @@ -73,6 +76,14 @@ public WebHeaderCollection Headers } } + public int TimeoutInMilliSeconds + { + set + { + this.timeoutInMilliSeconds = value; + } + } + public async Task GetResponseSyncOrAsync(CallState callState) { if (this.BodyParameters != null) @@ -86,10 +97,42 @@ public async Task GetResponseSyncOrAsync(CallState callState) #if ADAL_NET if (callState != null && callState.CallSync) { + this.request.Timeout = this.timeoutInMilliSeconds; return NetworkPlugin.HttpWebRequestFactory.CreateResponse(this.request.GetResponse()); } + + Task 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 - return NetworkPlugin.HttpWebRequestFactory.CreateResponse(await this.request.GetResponseAsync()); } public async Task GetRequestStreamSyncOrAsync(CallState callState) diff --git a/tests/Test.ADAL.NET.Unit/Test.ADAL.NET.Unit.csproj b/tests/Test.ADAL.NET.Unit/Test.ADAL.NET.Unit.csproj index 7c53c0eeb..c01943078 100644 --- a/tests/Test.ADAL.NET.Unit/Test.ADAL.NET.Unit.csproj +++ b/tests/Test.ADAL.NET.Unit/Test.ADAL.NET.Unit.csproj @@ -17,6 +17,8 @@ False UnitTest TEST_ADAL_NET + ..\..\ + true true @@ -45,7 +47,23 @@ true + + False + ..\..\packages\Microsoft.Owin.2.1.0\lib\net45\Microsoft.Owin.dll + + + False + ..\..\packages\Microsoft.Owin.Host.HttpListener.2.1.0\lib\net45\Microsoft.Owin.Host.HttpListener.dll + + + False + ..\..\packages\Microsoft.Owin.Hosting.2.1.0\lib\net45\Microsoft.Owin.Hosting.dll + + + False + ..\..\packages\Owin.1.0\lib\net40\Owin.dll + @@ -137,6 +155,7 @@ valid_cert2.pfx PreserveNewest + @@ -158,6 +177,13 @@ + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + +