private void AssertAccountCacheItemsAreEqual(MsalAccountCacheItem expected, MsalAccountCacheItem actual) { AssertCacheItemBaseItemsAreEqual(expected, actual); Assert.AreEqual(expected.PreferredUsername, actual.PreferredUsername, nameof(actual.PreferredUsername)); Assert.AreEqual(expected.Name, actual.Name, nameof(actual.Name)); Assert.AreEqual(expected.GivenName, actual.GivenName, nameof(actual.GivenName)); Assert.AreEqual(expected.FamilyName, actual.FamilyName, nameof(actual.FamilyName)); Assert.AreEqual(expected.LocalAccountId, actual.LocalAccountId, nameof(actual.LocalAccountId)); Assert.AreEqual(expected.AuthorityType, actual.AuthorityType, nameof(actual.AuthorityType)); Assert.AreEqual(expected.TenantId, actual.TenantId, nameof(actual.TenantId)); CoreAssert.AssertDictionariesAreEqual(expected.WamAccountIds, actual.WamAccountIds, StringComparer.Ordinal); }
private static void AssertTsAndJwkClaims(IPoPCryptoProvider popCryptoProvider, System.Security.Claims.ClaimsPrincipal claims) { long ts = long.Parse(claims.FindAll("ts").Single().Value); CoreAssert.IsWithinRange(DateTimeOffset.UtcNow, DateTimeHelpers.UnixTimestampToDateTime(ts), TimeSpan.FromSeconds(5)); string jwkClaim = claims.FindAll("cnf").Single().Value; JToken publicKey = JToken.Parse(popCryptoProvider.CannonicalPublicKeyJwk); JObject jwkInConfig = new JObject(new JProperty(PoPClaimTypes.JWK, publicKey)); var jwkInToken = JObject.Parse(jwkClaim); Assert.IsTrue(JObject.DeepEquals(jwkInConfig, jwkInToken)); }
public void IdTokenParsing_AADToken() { /* * "aud": "b6c69a37-df96-4db0-9088-2ab96e1d8215", * "iss": "https://login.microsoftonline.com/f645ad92-e38d-4d1a-b510-d1b09a74a8ca/v2.0", * "iat": 1538538422, * "nbf": 1538538422, * "exp": 1538542322, * "name": "Cloud IDLAB Basic User", * "oid": "9f4880d8-80ba-4c40-97bc-f7a23c703084", * "preferred_username": "******", * "sub": "Y6YkBdHNNLHNmTKel9KhRz8wrasxdLRFiP14BRPWrn4", * "tid": "f645ad92-e38d-4d1a-b510-d1b09a74a8ca", * "uti": "6nciX02SMki9k73-F1sZAA", * "ver": "2.0" */ var addIdToken = TestConstants.CreateAadTestTokenResponse().IdToken; var parsedToken = IdToken.Parse(addIdToken); CoreAssert.AreEqual("Cloud IDLAB Basic User", parsedToken.Name, parsedToken.ClaimsPrincipal.FindFirst("name").Value); CoreAssert.AreEqual("9f4880d8-80ba-4c40-97bc-f7a23c703084", parsedToken.ObjectId, parsedToken.ClaimsPrincipal.FindFirst("oid").Value); CoreAssert.AreEqual("*****@*****.**", parsedToken.PreferredUsername, parsedToken.ClaimsPrincipal.FindFirst("preferred_username").Value); CoreAssert.AreEqual("Y6YkBdHNNLHNmTKel9KhRz8wrasxdLRFiP14BRPWrn4", parsedToken.Subject, parsedToken.ClaimsPrincipal.FindFirst("sub").Value); CoreAssert.AreEqual("f645ad92-e38d-4d1a-b510-d1b09a74a8ca", parsedToken.TenantId, parsedToken.ClaimsPrincipal.FindFirst("tid").Value); Assert.AreEqual("b6c69a37-df96-4db0-9088-2ab96e1d8215", parsedToken.ClaimsPrincipal.Claims.Single(c => c.Type == "aud").Value); Assert.AreEqual("https://login.microsoftonline.com/f645ad92-e38d-4d1a-b510-d1b09a74a8ca/v2.0", parsedToken.ClaimsPrincipal.Claims.Single(c => c.Type == "iss").Value); Assert.AreEqual("1538538422", parsedToken.ClaimsPrincipal.Claims.Single(c => c.Type == "iat").Value); Assert.AreEqual("1538538422", parsedToken.ClaimsPrincipal.Claims.Single(c => c.Type == "nbf").Value); Assert.AreEqual("1538542322", parsedToken.ClaimsPrincipal.Claims.Single(c => c.Type == "exp").Value); Assert.AreEqual("Cloud IDLAB Basic User", parsedToken.ClaimsPrincipal.Claims.Single(c => c.Type == "name").Value); Assert.AreEqual("9f4880d8-80ba-4c40-97bc-f7a23c703084", parsedToken.ClaimsPrincipal.Claims.Single(c => c.Type == "oid").Value); Assert.AreEqual("*****@*****.**", parsedToken.ClaimsPrincipal.Claims.Single(c => c.Type == "preferred_username").Value); Assert.AreEqual("Y6YkBdHNNLHNmTKel9KhRz8wrasxdLRFiP14BRPWrn4", parsedToken.ClaimsPrincipal.Claims.Single(c => c.Type == "sub").Value); Assert.AreEqual("f645ad92-e38d-4d1a-b510-d1b09a74a8ca", parsedToken.ClaimsPrincipal.Claims.Single(c => c.Type == "tid").Value); Assert.AreEqual("6nciX02SMki9k73-F1sZAA", parsedToken.ClaimsPrincipal.Claims.Single(c => c.Type == "uti").Value); Assert.AreEqual("2.0", parsedToken.ClaimsPrincipal.Claims.Single(c => c.Type == "ver").Value); Assert.IsTrue(parsedToken.ClaimsPrincipal.Claims.Where(c => (new[] { "nbf", "iat", "exp" }).Contains(c.Type) == true).All(c => c.ValueType == ClaimValueTypes.Integer.ToString())); Assert.IsTrue(parsedToken.ClaimsPrincipal.Claims.Where(c => (new[] { "nbf", "iat", "exp" }).Contains(c.Type) == false).All(c => c.ValueType == ClaimValueTypes.String.ToString())); Assert.IsNull(parsedToken.Upn); Assert.IsNull(parsedToken.FamilyName); Assert.IsNull(parsedToken.GivenName); Assert.IsTrue(parsedToken.ClaimsPrincipal.Claims.All(c => c.Issuer == "https://login.microsoftonline.com/f645ad92-e38d-4d1a-b510-d1b09a74a8ca/v2.0")); Assert.IsTrue(parsedToken.ClaimsPrincipal.Claims.All(c => c.OriginalIssuer == "https://login.microsoftonline.com/f645ad92-e38d-4d1a-b510-d1b09a74a8ca/v2.0")); }
public void ValidateCommonParameters( ApiEvent.ApiIds expectedApiId, string expectedAuthorityOverride = null, Dictionary <string, string> expectedExtraQueryParameters = null, IEnumerable <string> expectedScopes = null) { Assert.IsNotNull(CommonParametersReceived); Assert.AreEqual(expectedApiId, CommonParametersReceived.ApiId); Assert.AreEqual(expectedAuthorityOverride, CommonParametersReceived.AuthorityOverride); CoreAssert.AreScopesEqual( (expectedScopes ?? MsalTestConstants.Scope).AsSingleString(), CommonParametersReceived.Scopes.AsSingleString()); CollectionAssert.AreEqual( expectedExtraQueryParameters, CommonParametersReceived.ExtraQueryParameters?.ToList()); }
public void AccessToken_WithKidAndType_FromMsalResponseJson() { // Arrange string json = TestConstants.TokenResponseJson; json = JsonTestUtils.AddKeyValue(json, StorageJsonKeys.TokenType, "pop"); var tokenResponse = JsonHelper.DeserializeFromJson <MsalTokenResponse>(json); // Act MsalAccessTokenCacheItem at = new MsalAccessTokenCacheItem(TestConstants.ProductionPrefNetworkEnvironment, TestConstants.ClientId, tokenResponse, TestConstants.TenantId, keyId: "kid1"); // Assert Assert.AreEqual("kid1", at.KeyId); CoreAssert.AreEqual(tokenResponse.TokenType, at.TokenType, "pop"); }
public void ValidateInteractiveParameters( IAccount expectedAccount = null, IEnumerable <string> expectedExtraScopesToConsent = null, string expectedLoginHint = null, string expectedPromptValue = null, bool expectedEmbeddedWebView = false, ICustomWebUi expectedCustomWebUi = null) { Assert.IsNotNull(InteractiveParametersReceived); Assert.AreEqual(expectedAccount, InteractiveParametersReceived.Account); CoreAssert.AreScopesEqual( (expectedExtraScopesToConsent ?? new List <string>()).AsSingleString(), InteractiveParametersReceived.ExtraScopesToConsent.AsSingleString()); Assert.AreEqual(expectedLoginHint, InteractiveParametersReceived.LoginHint); Assert.AreEqual(expectedPromptValue ?? Prompt.SelectAccount.PromptValue, InteractiveParametersReceived.Prompt.PromptValue); Assert.IsNotNull(InteractiveParametersReceived.UiParent); Assert.AreEqual(expectedEmbeddedWebView, InteractiveParametersReceived.UseEmbeddedWebView); Assert.AreEqual(expectedCustomWebUi, InteractiveParametersReceived.CustomWebUi); }
private static void AssertPreviousTelemetry( HttpRequestMessage requestMessage, int expectedSilentCount, ApiIds[] expectedFailedApiIds = null, Guid[] expectedCorrelationIds = null, string[] expectedErrors = null, string[] expectedRegions = null, string[] expectedRegionSources = null) { expectedFailedApiIds = expectedFailedApiIds ?? new ApiIds[0]; expectedCorrelationIds = expectedCorrelationIds ?? new Guid[0]; expectedErrors = expectedErrors ?? new string[0]; expectedRegions = expectedRegions ?? new string[0]; expectedRegionSources = expectedRegionSources ?? new string[0]; var actualHeader = ParseLastRequestHeader(requestMessage); Assert.AreEqual(expectedSilentCount, actualHeader.SilentCount); CoreAssert.AreEqual(actualHeader.FailedApis.Length, actualHeader.CorrelationIds.Length, actualHeader.Errors.Length); CollectionAssert.AreEqual( expectedFailedApiIds.Select(apiId => ((int)apiId).ToString(CultureInfo.InvariantCulture)).ToArray(), actualHeader.FailedApis); CollectionAssert.AreEqual( expectedCorrelationIds.Select(g => g.ToString()).ToArray(), actualHeader.CorrelationIds); CollectionAssert.AreEqual( expectedErrors, actualHeader.Errors); CollectionAssert.AreEqual( expectedRegions, actualHeader.Regions); CollectionAssert.AreEqual( expectedRegionSources, actualHeader.RegionSources); }
public async Task KnownInstanceMetadataIsUpToDateAsync() { const string validDiscoveryUri = @"https://login.microsoftonline.com/common/discovery/instance?api-version=1.1&authorization_endpoint=https%3A%2F%2Flogin.microsoftonline.com%2Fcommon%2Foauth2%2Fv2.0%2Fauthorize"; const string validPpeDiscoveryUri = @"https://login.windows-ppe.net/common/discovery/instance?api-version=1.1&authorization_endpoint=https%3A%2F%2Flogin.microsoftonline.com%2Fcommon%2Foauth2%2Fv2.0%2Fauthorize"; HttpClient httpClient = new HttpClient(); HttpResponseMessage discoveryResponse = await httpClient.SendAsync( new HttpRequestMessage( HttpMethod.Get, validDiscoveryUri)).ConfigureAwait(false); string discoveryJson = await discoveryResponse.Content.ReadAsStringAsync().ConfigureAwait(false); HttpResponseMessage ppeDiscoveryResponse = await httpClient.SendAsync( new HttpRequestMessage( HttpMethod.Get, validPpeDiscoveryUri)).ConfigureAwait(false); string ppeDiscoveryJson = await ppeDiscoveryResponse.Content.ReadAsStringAsync().ConfigureAwait(false); InstanceDiscoveryMetadataEntry[] actualMetadata = JsonHelper.DeserializeFromJson <InstanceDiscoveryResponse>(discoveryJson).Metadata; InstanceDiscoveryMetadataEntry[] actualPpeMetadata = JsonHelper.DeserializeFromJson <InstanceDiscoveryResponse>(ppeDiscoveryJson).Metadata; var processedMetadata = new Dictionary <string, InstanceDiscoveryMetadataEntry>(); foreach (InstanceDiscoveryMetadataEntry entry in actualMetadata.Concat(actualPpeMetadata)) { foreach (var alias in entry.Aliases) { processedMetadata[alias] = entry; } } IDictionary <string, InstanceDiscoveryMetadataEntry> expectedMetadata = KnownMetadataProvider.GetAllEntriesForTest(); CoreAssert.AssertDictionariesAreEqual( expectedMetadata, processedMetadata, new InstanceDiscoveryMetadataEntryComparer()); }
public void ValidateInteractiveParameters( WebViewPreference expectedEmbeddedWebView, IAccount expectedAccount = null, IEnumerable <string> expectedExtraScopesToConsent = null, string expectedLoginHint = null, string expectedPromptValue = null, ICustomWebUi expectedCustomWebUi = null, SystemWebViewOptions browserOptions = null) { Assert.IsNotNull(InteractiveParametersReceived); Assert.AreEqual(expectedAccount, InteractiveParametersReceived.Account); CoreAssert.AreScopesEqual( (expectedExtraScopesToConsent ?? new List <string>()).AsSingleString(), InteractiveParametersReceived.ExtraScopesToConsent.AsSingleString()); Assert.AreEqual(expectedLoginHint, InteractiveParametersReceived.LoginHint); Assert.AreEqual(expectedPromptValue ?? Prompt.NotSpecified.PromptValue, InteractiveParametersReceived.Prompt.PromptValue); Assert.IsNotNull(InteractiveParametersReceived.UiParent); Assert.AreEqual(expectedEmbeddedWebView, InteractiveParametersReceived.UseEmbeddedWebView); Assert.AreEqual(expectedCustomWebUi, InteractiveParametersReceived.CustomWebUi); Assert.AreEqual(browserOptions, InteractiveParametersReceived.UiParent.SystemWebViewOptions); }
public void AccessToken_WithRefresh_FromMsalResponseJson() { // Arrange string json = TestConstants.TokenResponseJson; json = JsonTestUtils.AddKeyValue(json, "refresh_in", "1800"); var tokenResponse = JsonHelper.DeserializeFromJson <MsalTokenResponse>(json); // Act MsalAccessTokenCacheItem at = new MsalAccessTokenCacheItem(TestConstants.ProductionPrefNetworkEnvironment, TestConstants.ClientId, tokenResponse, TestConstants.TenantId); // Assert Assert.AreEqual(tokenResponse.RefreshIn, 1800); Assert.IsTrue(at.RefreshOn.HasValue); CoreAssert.AreEqual( at.RefreshOn.Value, (at.CachedAtOffset + TimeSpan.FromSeconds(1800)), TimeSpan.FromSeconds(1)); }
public void ImmutableTest() { CoreAssert.IsImmutable <AadAuthority>(); CoreAssert.IsImmutable <AdfsAuthority>(); CoreAssert.IsImmutable <B2CAuthority>(); }
public async Task WAM_AccountIds_GetMerged_Async() { // Arrange using (var httpManager = new MockHttpManager()) { var cache = new InMemoryTokenCache(); httpManager.AddInstanceDiscoveryMockHandler(); var mockBroker = Substitute.For <IBroker>(); mockBroker.IsBrokerInstalledAndInvokable(AuthorityType.Aad).Returns(true); var msalTokenResponse1 = CreateMsalTokenResponseFromWam("wam1"); var msalTokenResponse2 = CreateMsalTokenResponseFromWam("wam2"); var msalTokenResponse3 = CreateMsalTokenResponseFromWam("wam3"); // 2 apps must share the token cache, like FOCI apps, for this test to be interesting var pca1 = PublicClientApplicationBuilder.Create(TestConstants.ClientId) .WithExperimentalFeatures(true) .WithTestBroker(mockBroker) .WithHttpManager(httpManager) .BuildConcrete(); var pca2 = PublicClientApplicationBuilder.Create(TestConstants.ClientId2) .WithExperimentalFeatures(true) .WithTestBroker(mockBroker) .WithHttpManager(httpManager) .BuildConcrete(); cache.Bind(pca1.UserTokenCache); cache.Bind(pca2.UserTokenCache); pca1.ServiceBundle.Config.BrokerCreatorFunc = (app, config, logger) => mockBroker; pca2.ServiceBundle.Config.BrokerCreatorFunc = (app, config, logger) => mockBroker; // Act mockBroker.AcquireTokenInteractiveAsync(null, null).ReturnsForAnyArgs(Task.FromResult(msalTokenResponse1)); await pca1.AcquireTokenInteractive(TestConstants.s_scope).ExecuteAsync().ConfigureAwait(false); // this should override wam1 id mockBroker.AcquireTokenInteractiveAsync(null, null).ReturnsForAnyArgs(Task.FromResult(msalTokenResponse2)); await pca1.AcquireTokenInteractive(TestConstants.s_scope).ExecuteAsync().ConfigureAwait(false); mockBroker.AcquireTokenInteractiveAsync(null, null).ReturnsForAnyArgs(Task.FromResult(msalTokenResponse3)); await pca2.AcquireTokenInteractive(TestConstants.s_scope).ExecuteAsync().ConfigureAwait(false); var accounts1 = await pca1.GetAccountsAsync().ConfigureAwait(false); var accounts2 = await pca2.GetAccountsAsync().ConfigureAwait(false); // Assert #if SUPPORTS_BROKER var wamAccountIds = (accounts1.Single() as Account).WamAccountIds; Assert.AreEqual(2, wamAccountIds.Count); Assert.AreEqual("wam2", wamAccountIds[TestConstants.ClientId]); Assert.AreEqual("wam3", wamAccountIds[TestConstants.ClientId2]); CoreAssert.AssertDictionariesAreEqual(wamAccountIds, (accounts2.Single() as Account).WamAccountIds, StringComparer.Ordinal); #else Assert.IsTrue(accounts1.All(a => (a as IAccountInternal).WamAccountIds == null)); Assert.IsTrue(accounts2.All(a => (a as IAccountInternal).WamAccountIds == null)); #endif } }
protected override Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { ActualRequestMessage = request; if (ExceptionToThrow != null) { throw ExceptionToThrow; } var uri = request.RequestUri; if (!string.IsNullOrEmpty(ExpectedUrl)) { Assert.AreEqual( ExpectedUrl, uri.AbsoluteUri.Split( new[] { '?' })[0]); } Assert.AreEqual(ExpectedMethod, request.Method); // Match QP passed in for validation. if (ExpectedQueryParams != null) { Assert.IsFalse( string.IsNullOrEmpty(uri.Query), string.Format( CultureInfo.InvariantCulture, "provided url ({0}) does not contain query parameters, as expected", uri.AbsolutePath)); IDictionary <string, string> inputQp = CoreHelpers.ParseKeyValueList(uri.Query.Substring(1), '&', false, null); Assert.AreEqual(ExpectedQueryParams.Count, inputQp.Count, "Different number of query params`"); foreach (string key in ExpectedQueryParams.Keys) { Assert.IsTrue( inputQp.ContainsKey(key), string.Format( CultureInfo.InvariantCulture, "expected QP ({0}) not found in the url ({1})", key, uri.AbsolutePath)); Assert.AreEqual(ExpectedQueryParams[key], inputQp[key]); } } if (ExpectedPostData != null) { string postData = request.Content.ReadAsStringAsync().Result; Dictionary <string, string> requestPostDataPairs = CoreHelpers.ParseKeyValueList(postData, '&', true, null); foreach (string key in ExpectedPostData.Keys) { Assert.IsTrue(requestPostDataPairs.ContainsKey(key)); if (key.Equals(OAuth2Parameter.Scope, StringComparison.OrdinalIgnoreCase)) { CoreAssert.AreScopesEqual(ExpectedPostData[key], requestPostDataPairs[key]); } else { Assert.AreEqual(ExpectedPostData[key], requestPostDataPairs[key]); } } } if (HttpTelemetryHeaders != null) { if (ActualRequestMessage.Headers.Contains(TelemetryConstants.XClientLastTelemetry)) { Assert.AreEqual(HttpTelemetryHeaders[TelemetryConstants.XClientLastTelemetry], ReturnValueFromRequestHeader(TelemetryConstants.XClientLastTelemetry)); Assert.AreEqual(HttpTelemetryHeaders[TelemetryConstants.XClientCurrentTelemetry], ReturnValueFromRequestHeader(TelemetryConstants.XClientCurrentTelemetry)); } } AdditionalRequestValidation?.Invoke(request); return(new TaskFactory().StartNew(() => ResponseMessage, cancellationToken)); }
protected override Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { ActualRequestMessage = request; if (ExceptionToThrow != null) { throw ExceptionToThrow; } var uri = request.RequestUri; if (!string.IsNullOrEmpty(ExpectedUrl)) { Assert.AreEqual( ExpectedUrl, uri.AbsoluteUri.Split( new[] { '?' })[0]); } Assert.AreEqual(ExpectedMethod, request.Method); // Match QP passed in for validation. if (ExpectedQueryParams != null) { Assert.IsFalse( string.IsNullOrEmpty(uri.Query), string.Format( CultureInfo.InvariantCulture, "provided url ({0}) does not contain query parameters, as expected", uri.AbsolutePath)); IDictionary <string, string> inputQp = CoreHelpers.ParseKeyValueList(uri.Query.Substring(1), '&', false, null); Assert.AreEqual(ExpectedQueryParams.Count, inputQp.Count, "Different number of query params`"); foreach (string key in ExpectedQueryParams.Keys) { Assert.IsTrue( inputQp.ContainsKey(key), string.Format( CultureInfo.InvariantCulture, "expected QP ({0}) not found in the url ({1})", key, uri.AbsolutePath)); Assert.AreEqual(ExpectedQueryParams[key], inputQp[key]); } } if (request.Method != HttpMethod.Get && request.Content != null) { string postData = request.Content.ReadAsStringAsync().Result; ActualRequestPostData = CoreHelpers.ParseKeyValueList(postData, '&', true, null); } if (ExpectedPostData != null) { foreach (string key in ExpectedPostData.Keys) { Assert.IsTrue(ActualRequestPostData.ContainsKey(key)); if (key.Equals(OAuth2Parameter.Scope, StringComparison.OrdinalIgnoreCase)) { CoreAssert.AreScopesEqual(ExpectedPostData[key], ActualRequestPostData[key]); } else { Assert.AreEqual(ExpectedPostData[key], ActualRequestPostData[key]); } } } if (ExpectedRequestHeaders != null) { foreach (var kvp in ExpectedRequestHeaders) { Assert.IsTrue( request.Headers.Any(h => string.Equals(h.Key, kvp.Key, StringComparison.OrdinalIgnoreCase) && string.Equals(h.Value.AsSingleString(), kvp.Value, StringComparison.OrdinalIgnoreCase)) , $"Expecting a request header {kvp.Key}: {kvp.Value} but did not find in the actual request: {request}"); } } if (UnexpectedRequestHeaders != null) { foreach (var item in UnexpectedRequestHeaders) { Assert.IsTrue( !request.Headers.Any(h => string.Equals(h.Key, item, StringComparison.OrdinalIgnoreCase)) , $"Not expecting a request header with key={item} but it was found in the actual request: {request}"); } } AdditionalRequestValidation?.Invoke(request); return(new TaskFactory().StartNew(() => ResponseMessage, cancellationToken)); }