public async Task WithExtraQueryParamsAndClaimsAsync() { IDictionary <string, string> extraQueryParamsAndClaims = TestConstants.ExtraQueryParameters.ToDictionary(e => e.Key, e => e.Value); extraQueryParamsAndClaims.Add(OAuth2Parameter.Claims, TestConstants.Claims); using (MockHttpAndServiceBundle harness = CreateTestHarness()) { var cache = new TokenCache(harness.ServiceBundle, false); var ui = new MockWebUI() { MockResult = AuthorizationResult.FromUri(TestConstants.AuthorityHomeTenant + "?code=some-code"), QueryParamsToValidate = TestConstants.ExtraQueryParameters }; MsalMockHelpers.ConfigureMockWebUI(harness.ServiceBundle.PlatformProxy, ui); MockInstanceDiscoveryAndOpenIdRequest(harness.HttpManager); var tokenResponseHandler = new MockHttpMessageHandler { ExpectedMethod = HttpMethod.Post, ExpectedQueryParams = TestConstants.ExtraQueryParameters, ExpectedPostData = new Dictionary <string, string>() { { OAuth2Parameter.Claims, TestConstants.Claims } }, ResponseMessage = MockHelpers.CreateSuccessTokenResponseMessage() }; harness.HttpManager.AddMockHandler(tokenResponseHandler); AuthenticationRequestParameters parameters = harness.CreateAuthenticationRequestParameters( TestConstants.AuthorityHomeTenant, TestConstants.s_scope, cache, extraQueryParameters: TestConstants.ExtraQueryParameters, claims: TestConstants.Claims); parameters.RedirectUri = new Uri("some://uri"); parameters.LoginHint = TestConstants.DisplayableId; AcquireTokenInteractiveParameters interactiveParameters = new AcquireTokenInteractiveParameters { Prompt = Prompt.SelectAccount, ExtraScopesToConsent = TestConstants.s_scopeForAnotherResource.ToArray(), }; var request = new InteractiveRequest( parameters, interactiveParameters); AuthenticationResult result = await request.RunAsync().ConfigureAwait(false); Assert.IsNotNull(result); Assert.AreEqual(1, ((ITokenCacheInternal)cache).Accessor.GetAllRefreshTokens().Count()); Assert.AreEqual(1, ((ITokenCacheInternal)cache).Accessor.GetAllAccessTokens().Count()); Assert.AreEqual(result.AccessToken, "some-access-token"); } }
[WorkItem(1418)] // test for bug https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/issues/1418 public async Task VerifyAuthorizationResult_NoErrorDescription_Async() { using (MockHttpAndServiceBundle harness = CreateTestHarness()) { MockInstanceDiscoveryAndOpenIdRequest(harness.HttpManager); MockWebUI webUi = new MockWebUI() { // error code and error description is empty string (not null) MockResult = AuthorizationResult.FromUri(TestConstants.AuthorityHomeTenant + "?error=some_error&error_description= "), }; MsalMockHelpers.ConfigureMockWebUI(harness.ServiceBundle.PlatformProxy, webUi); AuthenticationRequestParameters parameters = harness.CreateAuthenticationRequestParameters( TestConstants.AuthorityHomeTenant, TestConstants.s_scope, new TokenCache(harness.ServiceBundle, false)); var request = new InteractiveRequest( parameters, new AcquireTokenInteractiveParameters()); var ex = await AssertException.TaskThrowsAsync <MsalServiceException>( () => request.RunAsync(CancellationToken.None)) .ConfigureAwait(false); Assert.AreEqual("some_error", ex.ErrorCode); Assert.AreEqual("Unknown error", ex.Message); } }
public void B2CAcquireTokenWithValidateAuthorityTrueTest() { using (var httpManager = new MockHttpManager()) { PublicClientApplication app = PublicClientApplicationBuilder.Create(TestConstants.ClientId) .WithAuthority(new Uri(TestConstants.B2CLoginAuthority), true) .WithHttpManager(httpManager) .WithTelemetry(new TraceTelemetryConfig()) .BuildConcrete(); MsalMockHelpers.ConfigureMockWebUI( app.ServiceBundle.PlatformProxy, AuthorizationResult.FromUri(app.AppConfig.RedirectUri + "?code=some-code")); httpManager.AddMockHandlerForTenantEndpointDiscovery(TestConstants.B2CLoginAuthority); httpManager.AddSuccessTokenResponseMockHandlerForPost(TestConstants.B2CLoginAuthority); AuthenticationResult result = app .AcquireTokenInteractive(TestConstants.s_scope) .ExecuteAsync(CancellationToken.None) .Result; Assert.IsNotNull(result); Assert.IsNotNull(result.Account); } }
public async Task ClaimsAndClientCapabilities_AreMerged_And_AreSentTo_AuthorizationEndpoint_And_TokenEndpoint_Async() { // Arrange using (var harness = CreateTestHarness()) { harness.HttpManager.AddInstanceDiscoveryMockHandler(); var app = PublicClientApplicationBuilder.Create(TestConstants.ClientId) .WithHttpManager(harness.HttpManager) .WithClientCapabilities(TestConstants.ClientCapabilities) .WithTelemetry(new TraceTelemetryConfig()) .BuildConcrete(); var mockUi = MsalMockHelpers.ConfigureMockWebUI( app.ServiceBundle.PlatformProxy, AuthorizationResult.FromUri(app.AppConfig.RedirectUri + "?code=some-code")); mockUi.QueryParamsToValidate = new Dictionary <string, string> { { OAuth2Parameter.Claims, TestConstants.ClientCapabilitiesAndClaimsJson } }; harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost( TestConstants.AuthorityCommonTenant, bodyParameters: mockUi.QueryParamsToValidate); AuthenticationResult result = await app .AcquireTokenInteractive(TestConstants.s_scope) .WithClaims(TestConstants.Claims) .ExecuteAsync(CancellationToken.None) .ConfigureAwait(false); Assert.IsNotNull(result.Account); } }
public async Task B2CAcquireTokenWithValidateAuthorityTrueAndRandomAuthorityTest_Async() { using (var harness = base.CreateTestHarness()) { PublicClientApplication app = PublicClientApplicationBuilder.Create(TestConstants.ClientId) .WithAuthority(new Uri(TestConstants.B2CCustomDomain), true) .WithHttpManager(harness.HttpManager) .WithCachePartitioningAsserts(harness.ServiceBundle.PlatformProxy) .BuildConcrete(); MsalMockHelpers.ConfigureMockWebUI( app.ServiceBundle, AuthorizationResult.FromUri(app.AppConfig.RedirectUri + "?code=some-code")); harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(TestConstants.B2CCustomDomain); AuthenticationResult result = await app .AcquireTokenInteractive(TestConstants.s_scope) .ExecuteAsync() .ConfigureAwait(false); Assert.AreEqual(TokenSource.IdentityProvider, result.AuthenticationResultMetadata.TokenSource); await app.AcquireTokenSilent(TestConstants.s_scope, result.Account).ExecuteAsync().ConfigureAwait(false); Assert.AreEqual(TokenSource.IdentityProvider, result.AuthenticationResultMetadata.TokenSource); } }
private static void ValidateB2CLoginAuthority(MockHttpAndServiceBundle harness, string authority) { var app = PublicClientApplicationBuilder .Create(TestConstants.ClientId) .WithB2CAuthority(authority) .WithHttpManager(harness.HttpManager) .BuildConcrete(); var ui = new MockWebUI() { MockResult = AuthorizationResult.FromUri(authority + "?code=some-code") }; MsalMockHelpers.ConfigureMockWebUI(app.ServiceBundle.PlatformProxy, ui); harness.HttpManager.AddMockHandlerForTenantEndpointDiscovery(authority); harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(authority); var result = app .AcquireTokenInteractive(TestConstants.s_scope) .ExecuteAsync(CancellationToken.None) .Result; Assert.IsNotNull(result); Assert.IsNotNull(result.Account); }
public async Task AfterAccess_Is_Called_When_BeforeAceess_Throws_Async() { using (var harness = CreateTestHarness()) { var pca = PublicClientApplicationBuilder .Create(TestConstants.ClientId) .WithHttpManager(harness.HttpManager) .BuildConcrete(); var tokenCacheHelper = new TokenCacheHelper(); tokenCacheHelper.PopulateCache(pca.UserTokenCacheInternal.Accessor, addSecondAt: false); var account = (await pca.GetAccountsAsync().ConfigureAwait(false)).First(); // All these actions trigger a reloading of the cache await RunAfterAccessFailureAsync(pca, () => pca.GetAccountsAsync()).ConfigureAwait(false); await RunAfterAccessFailureAsync(pca, () => pca.AcquireTokenSilent(new[] { "User.Read" }, account).ExecuteAsync()) .ConfigureAwait(false); await RunAfterAccessFailureAsync(pca, () => pca.RemoveAsync(account)).ConfigureAwait(false); // AcquireTokenInteractive will save a token to the cache, but needs more setup harness.HttpManager.AddInstanceDiscoveryMockHandler(); harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(TestConstants.AuthorityCommonTenant); MsalMockHelpers.ConfigureMockWebUI(pca); await RunAfterAccessFailureAsync(pca, () => pca.AcquireTokenInteractive(new[] { "User.Read" }).ExecuteAsync()) .ConfigureAwait(false); } }
//Test for bug #1292 (https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/issues/1292) public void AuthorityCustomPortTest() { var customPortAuthority = "https://localhost:5215/common/"; using (var harness = CreateTestHarness()) { harness.HttpManager.AddInstanceDiscoveryMockHandler(customPortAuthority); PublicClientApplication app = PublicClientApplicationBuilder.Create(TestConstants.ClientId) .WithAuthority(new Uri(customPortAuthority), false) .WithHttpManager(harness.HttpManager) .BuildConcrete(); //Ensure that the PublicClientApplication init does not remove the port from the authority Assert.AreEqual(customPortAuthority, app.Authority); MsalMockHelpers.ConfigureMockWebUI( app.ServiceBundle.PlatformProxy, AuthorizationResult.FromUri(app.AppConfig.RedirectUri + "?code=some-code")); harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(customPortAuthority); harness.HttpManager.AddInstanceDiscoveryMockHandler(customPortAuthority); AuthenticationResult result = app .AcquireTokenInteractive(TestConstants.s_scope) .ExecuteAsync(CancellationToken.None) .Result; //Ensure that acquiring a token does not remove the port from the authority Assert.AreEqual(customPortAuthority, app.Authority); } }
private async Task InteractiveAsync(PublicClientApplication app, ServerTokenResponse serverTokenResponse) { if (serverTokenResponse == ServerTokenResponse.ErrorClientMismatch) { throw new NotImplementedException("test error"); } if (!_instanceAndEndpointRequestPerformed) { _instanceAndEndpointRequestPerformed = true; _harness.HttpManager.AddInstanceDiscoveryMockHandler(); _harness.HttpManager.AddMockHandlerForTenantEndpointDiscovery(MsalTestConstants.AuthorityUtidTenant); } MsalMockHelpers.ConfigureMockWebUI( app.ServiceBundle.PlatformProxy, AuthorizationResult.FromUri(MsalTestConstants.B2CLoginAuthority + "?code=some-code")); _harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost( MsalTestConstants.AuthorityUtidTenant, foci: serverTokenResponse == ServerTokenResponse.FociToken); // Acquire token interactively for A AuthenticationResult result = await app.AcquireTokenInteractive(MsalTestConstants.Scope).ExecuteAsync(CancellationToken.None).ConfigureAwait(false); Assert.IsNotNull(result.Account); AssertAppMetadata(app, serverTokenResponse == ServerTokenResponse.FociToken); }
public void PKeyAuthSuccsesResponseTest() { using (var harness = CreateTestHarness()) { harness.HttpManager.AddInstanceDiscoveryMockHandler(); PublicClientApplication app = PublicClientApplicationBuilder.Create(TestConstants.ClientId) .WithAuthority(new Uri(ClientApplicationBase.DefaultAuthority), true) .WithHttpManager(harness.HttpManager) .WithTelemetry(new TraceTelemetryConfig()) .BuildConcrete(); MsalMockHelpers.ConfigureMockWebUI( app.ServiceBundle.PlatformProxy, AuthorizationResult.FromUri(app.AppConfig.RedirectUri + "?code=some-code")); //Initiates PKeyAuth challenge which will trigger an additional request sent to AAD to satisfy the PKeyAuth challenge harness.HttpManager.AddMockHandler( new MockHttpMessageHandler { ExpectedMethod = HttpMethod.Post, ResponseMessage = MockHelpers.CreatePKeyAuthChallengeResponse() }); harness.HttpManager.AddMockHandler(CreateTokenResponseHttpHandlerWithPKeyAuthValidation()); AuthenticationResult result = app .AcquireTokenInteractive(TestConstants.s_scope) .ExecuteAsync(CancellationToken.None) .Result; } }
private async Task RunCacheFormatValidationAsync(MockHttpAndServiceBundle harness) { PublicClientApplication app = PublicClientApplicationBuilder .Create(_clientId) .WithAuthority(new Uri(_requestAuthority), true) .WithHttpManager(harness.HttpManager) .WithTelemetry(new TraceTelemetryConfig()) .BuildConcrete(); MsalMockHelpers.ConfigureMockWebUI( app.ServiceBundle.PlatformProxy, AuthorizationResult.FromUri(app.AppConfig.RedirectUri + "?code=some-code")); harness.HttpManager.AddMockHandler(new MockHttpMessageHandler { ExpectedMethod = HttpMethod.Post, ResponseMessage = MockHelpers.CreateSuccessResponseMessage(_tokenResponse) }); AuthenticationResult result = app .AcquireTokenInteractive(TestConstants.s_scope) .ExecuteAsync(CancellationToken.None) .Result; Assert.IsNotNull(result); await ValidateAtAsync(app.UserTokenCacheInternal).ConfigureAwait(false); await ValidateRtAsync(app.UserTokenCacheInternal).ConfigureAwait(false); await ValidateIdTokenAsync(app.UserTokenCacheInternal).ConfigureAwait(false); await ValidateAccountAsync(app.UserTokenCacheInternal).ConfigureAwait(false); }
public async Task DoNotCallPlatformProxyAsync() { // Arrange using (var harness = new MockHttpAndServiceBundle()) { harness.HttpManager.AddInstanceDiscoveryMockHandler(); var mockProxy = new MockProxy(); var app = PublicClientApplicationBuilder.Create(TestConstants.ClientId) .WithAuthority(new Uri(ClientApplicationBase.DefaultAuthority), true) .WithHttpManager(harness.HttpManager) .WithPlatformProxy(mockProxy) .WithRedirectUri("http://localhost") .BuildConcrete(); MsalMockHelpers.ConfigureMockWebUI( app.ServiceBundle.PlatformProxy, AuthorizationResult.FromUri(app.AppConfig.RedirectUri + "?code=some-code")); harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(TestConstants.AuthorityCommonTenant); // Act await app .AcquireTokenInteractive(TestConstants.s_scope) .ExecuteAsync() .ConfigureAwait(false); // Assert - NoDeviceIdProxy would fail if InternalGetDeviceId is called Assert.IsFalse(mockProxy.InternalDeviceIdWasCalled); } }
public async Task TestAccountAcrossMultipleClientIdsAsync() { using (var _harness = CreateTestHarness()) { // Arrange PublicClientApplication app = PublicClientApplicationBuilder .Create(TestConstants.ClientId) .WithHttpManager(_harness.HttpManager) .BuildConcrete(); Trace.WriteLine("Step 1 - call GetAccounts with empty cache - no accounts, no tokens"); var cacheAccessRecorder1 = app.UserTokenCache.RecordAccess(); var accounts = await app.GetAccountsAsync().ConfigureAwait(false); Assert.IsFalse(cacheAccessRecorder1.LastBeforeAccessNotificationArgs.HasTokens); Assert.IsNull(cacheAccessRecorder1.LastBeforeWriteNotificationArgs); Assert.IsFalse(cacheAccessRecorder1.LastAfterAccessNotificationArgs.HasTokens); Assert.IsFalse(accounts.Any()); Trace.WriteLine("Step 2 - call AcquireTokenInteractive - it will save new tokens in the cache"); MsalMockHelpers.ConfigureMockWebUI( app.ServiceBundle.PlatformProxy, AuthorizationResult.FromUri(app.AppConfig.RedirectUri + "?code=some-code")); _harness.HttpManager.AddInstanceDiscoveryMockHandler(); _harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(); var cacheAccessRecorder2 = app.UserTokenCache.RecordAccess(); await app .AcquireTokenInteractive(TestConstants.s_scope) .ExecuteAsync() .ConfigureAwait(false); Assert.IsFalse(cacheAccessRecorder2.LastBeforeAccessNotificationArgs.HasTokens); Assert.IsFalse(cacheAccessRecorder2.LastBeforeWriteNotificationArgs.HasTokens); Assert.IsTrue(cacheAccessRecorder2.LastAfterAccessNotificationArgs.HasTokens); Trace.WriteLine("Step 3 - call GetAccounts - now with 1 account"); var cacheAccessRecorder3 = app.UserTokenCache.RecordAccess(); accounts = await app.GetAccountsAsync().ConfigureAwait(false); Assert.IsTrue(cacheAccessRecorder3.LastBeforeAccessNotificationArgs.HasTokens); Assert.IsNull(cacheAccessRecorder3.LastBeforeWriteNotificationArgs); Assert.IsTrue(cacheAccessRecorder3.LastAfterAccessNotificationArgs.HasTokens); Assert.IsTrue(accounts.Any()); Trace.WriteLine("Step 4 - call RemoveAccounts - this will delete all the tokens"); var cacheAccessRecorder4 = app.UserTokenCache.RecordAccess(); await app.RemoveAsync(accounts.Single()).ConfigureAwait(false); Assert.IsTrue(cacheAccessRecorder4.LastBeforeAccessNotificationArgs.HasTokens); Assert.IsTrue(cacheAccessRecorder4.LastBeforeWriteNotificationArgs.HasTokens); Assert.IsFalse(cacheAccessRecorder4.LastAfterAccessNotificationArgs.HasTokens); } }
public async Task PKeyAuthSuccsesWithExtraQueryParamsResponseTestAsync() { using (var harness = CreateTestHarness()) { harness.HttpManager.AddInstanceDiscoveryMockHandler(); var builder = PublicClientApplicationBuilder.Create(TestConstants.ClientId) .WithAuthority("https://login.microsoftonline.com/common") .WithHttpManager(harness.HttpManager); builder.Config.DeviceAuthManagerForTest = Substitute.For <IDeviceAuthManager>(); Uri actualUri = null; builder.Config.DeviceAuthManagerForTest.TryCreateDeviceAuthChallengeResponseAsync( Arg.Any <HttpResponseHeaders>(), Arg.Any <Uri>(), out Arg.Any <string>()) .Returns(x => { x[2] = TestConstants.PKeyAuthResponse; actualUri = (Uri)x[1]; return(true); }); var pca = builder.BuildConcrete(); MsalMockHelpers.ConfigureMockWebUI( pca.ServiceBundle.PlatformProxy, AuthorizationResult.FromUri(pca.AppConfig.RedirectUri + "?code=some-code")); //Initiates PKeyAuth challenge which will trigger an additional request sent to AAD to satisfy the PKeyAuth challenge harness.HttpManager.AddMockHandler( new MockHttpMessageHandler { ExpectedMethod = HttpMethod.Post, ResponseMessage = MockHelpers.CreatePKeyAuthChallengeResponse() }); harness.HttpManager.AddMockHandler(CreateTokenResponseHttpHandlerWithPKeyAuthValidation()); AuthenticationResult result = await pca .AcquireTokenInteractive(TestConstants.s_scope) .WithExtraQueryParameters("qp1=v1") .ExecuteAsync() .ConfigureAwait(false); // Assert that the endpoint sent to the device auth manager doesn not have query params //await builder.Config.DeviceAuthManagerForTest.Received() // .TryCreateDeviceAuthChallengeResponseAsync(Arg.Any<HttpResponseHeaders>(), "foo", Arg.Any<string>()); Assert.AreEqual("https://login.microsoftonline.com/common/oauth2/v2.0/token", actualUri.AbsoluteUri); } }
private async Task ExecuteTestAsync( bool withTokenRequest, Action <ICustomWebUi> customizeWebUiBehavior, Func <InteractiveRequest, Task> executionBehavior) { var customWebUi = Substitute.For <ICustomWebUi>(); customizeWebUiBehavior(customWebUi); using (var harness = CreateTestHarness()) { MockInstanceDiscoveryAndOpenIdRequest(harness.HttpManager); if (withTokenRequest) { harness.HttpManager.AddMockHandler( new MockHttpMessageHandler { ExpectedMethod = HttpMethod.Post, ResponseMessage = MockHelpers.CreateSuccessTokenResponseMessage() }); } var parameters = harness.CreateAuthenticationRequestParameters( TestConstants.AuthorityHomeTenant, TestConstants.s_scope, new TokenCache(harness.ServiceBundle, false)); parameters.RedirectUri = new Uri(ExpectedRedirectUri); parameters.LoginHint = TestConstants.DisplayableId; var interactiveParameters = new AcquireTokenInteractiveParameters { Prompt = Prompt.ForceLogin, ExtraScopesToConsent = TestConstants.s_scopeForAnotherResource.ToArray(), CustomWebUi = customWebUi }; var ui = new CustomWebUiHandler(customWebUi); MsalMockHelpers.ConfigureMockWebUI(harness.ServiceBundle.PlatformProxy, ui); var request = new InteractiveRequest( parameters, interactiveParameters); await executionBehavior(request).ConfigureAwait(false); } }
public void DuplicateQueryParameterErrorTest() { using (MockHttpAndServiceBundle harness = CreateTestHarness()) { harness.HttpManager.AddInstanceDiscoveryMockHandler(); harness.HttpManager.AddMockHandlerForTenantEndpointDiscovery(TestConstants.AuthorityHomeTenant); AuthenticationRequestParameters parameters = harness.CreateAuthenticationRequestParameters( TestConstants.AuthorityHomeTenant, TestConstants.s_scope, new TokenCache(harness.ServiceBundle, false), extraQueryParameters: new Dictionary <string, string> { { "extra", "qp" }, { "prompt", "login" } }); parameters.RedirectUri = new Uri("some://uri"); parameters.LoginHint = TestConstants.DisplayableId; AcquireTokenInteractiveParameters interactiveParameters = new AcquireTokenInteractiveParameters { Prompt = Prompt.ForceLogin, ExtraScopesToConsent = TestConstants.s_scopeForAnotherResource.ToArray(), }; var request = new InteractiveRequest( parameters, interactiveParameters); MsalMockHelpers.ConfigureMockWebUI(harness.ServiceBundle.PlatformProxy, new MockWebUI()); try { request.RunAsync().Wait(); Assert.Fail("MsalException should be thrown here"); } catch (Exception exc) { Assert.IsTrue(exc.InnerException is MsalException); Assert.AreEqual( MsalError.DuplicateQueryParameterError, ((MsalException)exc.InnerException).ErrorCode); } } }
private void ValidateOathClient(HttpResponseMessage httpResponseMessage, Action <Exception> validationHandler) { using (MockHttpAndServiceBundle harness = CreateTestHarness()) { harness.HttpManager.AddInstanceDiscoveryMockHandler(); harness.HttpManager.AddMockHandler( new MockHttpMessageHandler { ExpectedMethod = HttpMethod.Get, ResponseMessage = httpResponseMessage }); AuthenticationRequestParameters parameters = harness.CreateAuthenticationRequestParameters( TestConstants.AuthorityHomeTenant, TestConstants.s_scope, new TokenCache(harness.ServiceBundle, false)); parameters.RedirectUri = new Uri("some://uri"); parameters.LoginHint = TestConstants.DisplayableId; AcquireTokenInteractiveParameters interactiveParameters = new AcquireTokenInteractiveParameters { Prompt = Prompt.SelectAccount, ExtraScopesToConsent = TestConstants.s_scopeForAnotherResource.ToArray(), }; MsalMockHelpers.ConfigureMockWebUI(harness.ServiceBundle.PlatformProxy, new MockWebUI()); var request = new InteractiveRequest( parameters, interactiveParameters); try { request.RunAsync().Wait(); Assert.Fail("MsalException should have been thrown here"); } catch (Exception exc) { validationHandler(exc); } } }
public async Task CustomInstanceDiscoveryMetadataUri_Async() { using (var harness = CreateTestHarness()) { var customMetadataUri = new Uri("https://custom.instance.discovery.uri"); var customAuthrority = "https://my.custom.authority/common/"; harness.HttpManager.AddInstanceDiscoveryMockHandler( customAuthrority, customMetadataUri, TestConstants.DiscoveryJsonResponse.Replace("login.microsoftonline.com", "my.custom.authority")); PublicClientApplication app = PublicClientApplicationBuilder .Create(TestConstants.ClientId) .WithAuthority(customAuthrority, false) .WithInstanceDiscoveryMetadata(customMetadataUri) .WithHttpManager(harness.HttpManager) .BuildConcrete(); MsalMockHelpers.ConfigureMockWebUI( app.ServiceBundle.PlatformProxy, AuthorizationResult.FromUri(app.AppConfig.RedirectUri + "?code=some-code")); // the rest of the communication with AAD happens on the preferred_network alias, not on login.windows.net harness.HttpManager.AddMockHandlerForTenantEndpointDiscovery(customAuthrority); harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(customAuthrority); AuthenticationResult result = await app .AcquireTokenInteractive(TestConstants.s_scope) .ExecuteAsync(CancellationToken.None) .ConfigureAwait(false); Assert.IsNotNull(result); Assert.IsNotNull(result.Account); Assert.AreEqual(TestConstants.UniqueId, result.UniqueId); Assert.AreEqual(TestConstants.CreateUserIdentifier(), result.Account.HomeAccountId.Identifier); Assert.AreEqual(TestConstants.DisplayableId, result.Account.Username); } }
public async Task AcquireTokenInterative_WithValidCustomInstanceMetadata_Async() { string instanceMetadataJson = File.ReadAllText( ResourceHelper.GetTestResourceRelativePath("CustomInstanceMetadata.json")); using (var harness = CreateTestHarness()) { // No instance discovery is made - it is important to not have this mock handler added // harness.HttpManager.AddInstanceDiscoveryMockHandler(); PublicClientApplication app = PublicClientApplicationBuilder .Create(TestConstants.ClientId) .WithAuthority(new Uri("https://login.windows.net/common/"), false) .WithInstanceDiscoveryMetadata(instanceMetadataJson) .WithHttpManager(harness.HttpManager) .WithTelemetry(new TraceTelemetryConfig()) .BuildConcrete(); MsalMockHelpers.ConfigureMockWebUI( app.ServiceBundle.PlatformProxy, AuthorizationResult.FromUri(app.AppConfig.RedirectUri + "?code=some-code")); // the rest of the communication with AAD happens on the preferred_network alias, not on login.windows.net harness.HttpManager.AddMockHandlerForTenantEndpointDiscovery(TestConstants.AuthorityCommonTenant); harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(TestConstants.AuthorityCommonTenant); AuthenticationResult result = await app .AcquireTokenInteractive(TestConstants.s_scope) .ExecuteAsync(CancellationToken.None) .ConfigureAwait(false); Assert.IsNotNull(result); Assert.IsNotNull(result.Account); Assert.AreEqual(TestConstants.UniqueId, result.UniqueId); Assert.AreEqual(TestConstants.CreateUserIdentifier(), result.Account.HomeAccountId.Identifier); Assert.AreEqual(TestConstants.DisplayableId, result.Account.Username); } }
public async Task B2CAcquireTokenWithResetPasswordTestAsync() { using (var httpManager = new MockHttpManager()) { PublicClientApplication app = PublicClientApplicationBuilder.Create(TestConstants.ClientId) .WithB2CAuthority(TestConstants.B2CLoginAuthority) .WithHttpManager(httpManager) .WithDebugLoggingCallback(logLevel: LogLevel.Verbose) .BuildConcrete(); // Interactive call and user wants to reset password var ui = new MockWebUI() { MockResult = AuthorizationResult.FromUri(TestConstants.B2CLoginAuthority + "?error=access_denied&error_description=AADB2C90091%3a+The+user+has+cancelled+entering+self-asserted+information.") }; httpManager.AddMockHandlerForTenantEndpointDiscovery(TestConstants.B2CLoginAuthority); MsalMockHelpers.ConfigureMockWebUI(app.ServiceBundle.PlatformProxy, ui); try { AuthenticationResult result = await app .AcquireTokenInteractive(TestConstants.s_scope) .ExecuteAsync(CancellationToken.None) .ConfigureAwait(false); } catch (MsalServiceException exc) { Assert.IsNotNull(exc); Assert.AreEqual("access_denied", exc.ErrorCode); Assert.AreEqual("AADB2C90091: The user has cancelled entering self-asserted information.", exc.Message); return; } } Assert.Fail("Should not reach here. Exception was not thrown."); }
public async Task B2C_NoScopes_NoAccessToken_Async() { using (var httpManager = new MockHttpManager()) { PublicClientApplication app = PublicClientApplicationBuilder.Create(TestConstants.ClientId) .WithAuthority(new Uri(TestConstants.B2CLoginAuthority), true) .WithHttpManager(httpManager) .BuildConcrete(); MsalMockHelpers.ConfigureMockWebUI( app.ServiceBundle.PlatformProxy, AuthorizationResult.FromUri(app.AppConfig.RedirectUri + "?code=some-code")); // Arrange 1 - interactive call with 0 scopes httpManager.AddMockHandlerForTenantEndpointDiscovery(TestConstants.B2CLoginAuthority); httpManager.AddSuccessTokenResponseMockHandlerForPost( TestConstants.B2CLoginAuthority, responseMessage: MockHelpers.CreateSuccessResponseMessage(MockHelpers.B2CTokenResponseWithoutAT)); // Act AuthenticationResult result = await app .AcquireTokenInteractive(null) // no scopes -> no Access Token! .ExecuteAsync() .ConfigureAwait(false); // Assert AssertNoAccessToken(result); Assert.AreEqual(0, httpManager.QueueSize); var ex = await AssertException.TaskThrowsAsync <MsalUiRequiredException>(() => app.AcquireTokenSilent(null, result.Account).ExecuteAsync() ).ConfigureAwait(false); Assert.AreEqual(MsalError.ScopesRequired, ex.ErrorCode); Assert.AreEqual(UiRequiredExceptionClassification.AcquireTokenSilentFailed, ex.Classification); } }
public void RunCacheFormatValidation() { using (var httpManager = new MockHttpManager()) { var serviceBundle = ServiceBundle.CreateWithCustomHttpManager(httpManager); TestInitialize(httpManager); PublicClientApplication app = new PublicClientApplication(serviceBundle, ClientId, RequestAuthority); MockWebUI ui = new MockWebUI() { MockResult = new AuthorizationResult(AuthorizationStatus.Success, MsalTestConstants.AuthorityHomeTenant + "?code=some-code") }; MsalMockHelpers.ConfigureMockWebUI(new AuthorizationResult(AuthorizationStatus.Success, app.RedirectUri + "?code=some-code")); //add mock response for tenant endpoint discovery httpManager.AddMockHandler(new MockHttpMessageHandler { Method = HttpMethod.Get, ResponseMessage = MockHelpers.CreateOpenIdConfigurationResponse(MsalTestConstants.AuthorityHomeTenant) }); httpManager.AddMockHandler(new MockHttpMessageHandler { Method = HttpMethod.Post, ResponseMessage = MockHelpers.CreateSuccessResponseMessage(TokenResponse) }); AuthenticationResult result = app.AcquireTokenAsync(MsalTestConstants.Scope).Result; Assert.IsNotNull(result); ValidateAt(app.UserTokenCache); ValidateRt(app.UserTokenCache); ValidateIdToken(app.UserTokenCache); ValidateAccount(app.UserTokenCache); } }
public void UnifiedCache_RemoveAccountIsApplicationSpecific() { byte[] data = null; using (var httpManager = new MockHttpManager()) { // login to app var app = PublicClientApplicationBuilder.Create(MsalTestConstants.ClientId) .WithAuthority(new Uri(ClientApplicationBase.DefaultAuthority), true) .WithHttpManager(httpManager) .WithTelemetry(new TraceTelemetryConfig()) .BuildConcrete(); app.UserTokenCache.SetBeforeAccess((TokenCacheNotificationArgs args) => { args.TokenCache.DeserializeMsalV3(data); }); app.UserTokenCache.SetAfterAccess((TokenCacheNotificationArgs args) => { data = args.TokenCache.SerializeMsalV3(); }); httpManager.AddInstanceDiscoveryMockHandler(); MsalMockHelpers.ConfigureMockWebUI( app.ServiceBundle.PlatformProxy, AuthorizationResult.FromUri(app.AppConfig.RedirectUri + "?code=some-code")); httpManager.AddMockHandlerForTenantEndpointDiscovery(MsalTestConstants.AuthorityCommonTenant); httpManager.AddSuccessTokenResponseMockHandlerForPost(ClientApplicationBase.DefaultAuthority); AuthenticationResult result = app .AcquireTokenInteractive(MsalTestConstants.Scope) .ExecuteAsync(CancellationToken.None) .Result; Assert.IsNotNull(result); Assert.AreEqual(1, app.UserTokenCacheInternal.Accessor.GetAllAccounts().Count()); Assert.AreEqual(1, app.GetAccountsAsync().Result.Count()); // login to app1 with same credentials var app1 = PublicClientApplicationBuilder.Create(MsalTestConstants.ClientId2) .WithHttpManager(httpManager) .WithTelemetry(new TraceTelemetryConfig()) .WithAuthority( new Uri(ClientApplicationBase.DefaultAuthority), true).BuildConcrete(); MsalMockHelpers.ConfigureMockWebUI( app1.ServiceBundle.PlatformProxy, AuthorizationResult.FromUri(app.AppConfig.RedirectUri + "?code=some-code")); app1.UserTokenCache.SetBeforeAccess((TokenCacheNotificationArgs args) => { args.TokenCache.DeserializeMsalV3(data); }); app1.UserTokenCache.SetAfterAccess((TokenCacheNotificationArgs args) => { data = args.TokenCache.SerializeMsalV3(); }); httpManager.AddSuccessTokenResponseMockHandlerForPost(ClientApplicationBase.DefaultAuthority); result = app1 .AcquireTokenInteractive(MsalTestConstants.Scope) .ExecuteAsync(CancellationToken.None) .Result; Assert.IsNotNull(result); // make sure that only one account cache entity was created Assert.AreEqual(1, app1.GetAccountsAsync().Result.Count()); Assert.AreEqual(2, app1.UserTokenCacheInternal.Accessor.GetAllAccessTokens().Count()); Assert.AreEqual(2, app1.UserTokenCacheInternal.Accessor.GetAllRefreshTokens().Count()); Assert.AreEqual(2, app1.UserTokenCacheInternal.Accessor.GetAllIdTokens().Count()); Assert.AreEqual(1, app1.UserTokenCacheInternal.Accessor.GetAllAccounts().Count()); // remove account from app app.RemoveAsync(app.GetAccountsAsync().Result.First()).Wait(); // make sure account removed from app Assert.AreEqual(0, app.GetAccountsAsync().Result.Count()); // make sure account Not removed from app1 Assert.AreEqual(1, app1.GetAccountsAsync().Result.Count()); } }
public void UnifiedCache_MsalStoresToAndReadRtFromAdalCache() { using (var httpManager = new MockHttpManager()) { httpManager.AddInstanceDiscoveryMockHandler(); var app = PublicClientApplicationBuilder.Create(MsalTestConstants.ClientId) .WithAuthority(new Uri(ClientApplicationBase.DefaultAuthority), true) .WithHttpManager(httpManager) .WithTelemetry(new TraceTelemetryConfig()) .WithUserTokenLegacyCachePersistenceForTest( new TestLegacyCachePersistance()) .BuildConcrete(); MsalMockHelpers.ConfigureMockWebUI( app.ServiceBundle.PlatformProxy, AuthorizationResult.FromUri(app.AppConfig.RedirectUri + "?code=some-code")); httpManager.AddMockHandlerForTenantEndpointDiscovery(MsalTestConstants.AuthorityCommonTenant); httpManager.AddSuccessTokenResponseMockHandlerForPost(ClientApplicationBase.DefaultAuthority); AuthenticationResult result = app.AcquireTokenInteractive(MsalTestConstants.Scope).ExecuteAsync(CancellationToken.None).Result; Assert.IsNotNull(result); // make sure Msal stored RT in Adal cache IDictionary <AdalTokenCacheKey, AdalResultWrapper> adalCacheDictionary = AdalCacheOperations.Deserialize(app.ServiceBundle.DefaultLogger, app.UserTokenCacheInternal.LegacyPersistence.LoadCache()); Assert.IsTrue(adalCacheDictionary.Count == 1); var requestContext = new RequestContext(app.ServiceBundle, Guid.NewGuid()); var accounts = app.UserTokenCacheInternal.GetAccountsAsync( MsalTestConstants.AuthorityCommonTenant, requestContext).Result; foreach (IAccount account in accounts) { app.UserTokenCacheInternal.RemoveMsalAccountWithNoLocks(account, requestContext); } httpManager.AddMockHandler( new MockHttpMessageHandler() { ExpectedMethod = HttpMethod.Post, ExpectedPostData = new Dictionary <string, string>() { { "grant_type", "refresh_token" } }, ResponseMessage = MockHelpers.CreateSuccessTokenResponseMessage( MsalTestConstants.UniqueId, MsalTestConstants.DisplayableId, MsalTestConstants.Scope.ToArray()) }); // Using RT from Adal cache for silent call AuthenticationResult result1 = app .AcquireTokenSilent(MsalTestConstants.Scope, result.Account) .WithAuthority(MsalTestConstants.AuthorityCommonTenant) .WithForceRefresh(false) .ExecuteAsync(CancellationToken.None) .Result; Assert.IsNotNull(result1); } }
private async Task <(HttpRequestMessage HttpRequest, Guid Correlationid)> RunAcquireTokenInteractiveAsync( AcquireTokenInteractiveOutcome outcome) { MockHttpMessageHandler tokenRequestHandler = null; Guid correlationId = default; switch (outcome) { case AcquireTokenInteractiveOutcome.Success: MsalMockHelpers.ConfigureMockWebUI( _app.ServiceBundle.PlatformProxy, AuthorizationResult.FromUri(_app.AppConfig.RedirectUri + "?code=some-code")); tokenRequestHandler = _harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(); var authResult = await _app .AcquireTokenInteractive(TestConstants.s_scope) .ExecuteAsync() .ConfigureAwait(false); correlationId = authResult.CorrelationId; break; case AcquireTokenInteractiveOutcome.AuthorizationError: correlationId = Guid.NewGuid(); var ui = Substitute.For <IWebUI>(); ui.UpdateRedirectUri(Arg.Any <Uri>()).Returns(new Uri("http://localhost:1234")); ui.AcquireAuthorizationAsync(null, null, null, default).ThrowsForAnyArgs( new MsalClientException("user_cancelled")); MsalMockHelpers.ConfigureMockWebUI(_app.ServiceBundle.PlatformProxy, ui); var ex = await AssertException.TaskThrowsAsync <MsalClientException>(() => _app .AcquireTokenInteractive(TestConstants.s_scope) .WithCorrelationId(correlationId) .ExecuteAsync()) .ConfigureAwait(false); break; case AcquireTokenInteractiveOutcome.AADUnavailableError: correlationId = Guid.NewGuid(); MsalMockHelpers.ConfigureMockWebUI( _app.ServiceBundle.PlatformProxy, AuthorizationResult.FromUri(_app.AppConfig.RedirectUri + "?code=some-code")); tokenRequestHandler = new MockHttpMessageHandler() { ExpectedMethod = HttpMethod.Post, ResponseMessage = MockHelpers.CreateFailureMessage( System.Net.HttpStatusCode.GatewayTimeout, "gateway timeout") }; var tokenRequestHandler2 = new MockHttpMessageHandler() { ExpectedMethod = HttpMethod.Post, ResponseMessage = MockHelpers.CreateFailureMessage( System.Net.HttpStatusCode.GatewayTimeout, "gateway timeout") }; // 2 of these are needed because MSAL has a "retry once" policy for 5xx errors _harness.HttpManager.AddMockHandler(tokenRequestHandler2); _harness.HttpManager.AddMockHandler(tokenRequestHandler); var serviceEx = await AssertException.TaskThrowsAsync <MsalServiceException>(() => _app .AcquireTokenInteractive(TestConstants.s_scope) .WithCorrelationId(correlationId) .ExecuteAsync()) .ConfigureAwait(false); break; default: throw new NotImplementedException(); } Assert.AreEqual(0, _harness.HttpManager.QueueSize); return(tokenRequestHandler?.ActualRequestMessage, correlationId); }
public async Task AuthorityMigrationTestAsync() { // make sure that for all network calls "preferred_cache" environment is used // (it is taken from metadata in instance discovery response), // except very first network call - instance discovery using (var httpManager = new MockHttpManager()) { var authorityUri = new Uri( string.Format( CultureInfo.InvariantCulture, "https://{0}/common", TestConstants.ProductionNotPrefEnvironmentAlias)); httpManager.AddInstanceDiscoveryMockHandler(authorityUri.AbsoluteUri); PublicClientApplication app = PublicClientApplicationBuilder .Create(TestConstants.ClientId) .WithAuthority(authorityUri, true) .WithHttpManager(httpManager) .WithUserTokenLegacyCachePersistenceForTest(new TestLegacyCachePersistance()) .WithTelemetry(new TraceTelemetryConfig()) .WithDebugLoggingCallback() .BuildConcrete(); // mock for openId config request httpManager.AddMockHandler(new MockHttpMessageHandler { ExpectedUrl = string.Format(CultureInfo.InvariantCulture, "https://{0}/common/v2.0/.well-known/openid-configuration", TestConstants.ProductionPrefNetworkEnvironment), ExpectedMethod = HttpMethod.Get, ResponseMessage = MockHelpers.CreateOpenIdConfigurationResponse(TestConstants.AuthorityHomeTenant) }); // mock webUi authorization MsalMockHelpers.ConfigureMockWebUI( app.ServiceBundle.PlatformProxy, AuthorizationResult.FromUri(app.AppConfig.RedirectUri + "?code=some-code"), null, TestConstants.ProductionPrefNetworkEnvironment); // mock token request httpManager.AddMockHandler(new MockHttpMessageHandler { ExpectedUrl = string.Format(CultureInfo.InvariantCulture, "https://{0}/home/oauth2/v2.0/token", TestConstants.ProductionPrefNetworkEnvironment), ExpectedMethod = HttpMethod.Post, ResponseMessage = MockHelpers.CreateSuccessTokenResponseMessage() }); AuthenticationResult result = app.AcquireTokenInteractive(TestConstants.s_scope).ExecuteAsync(CancellationToken.None).Result; // make sure that all cache entities are stored with "preferred_cache" environment // (it is taken from metadata in instance discovery response) await ValidateCacheEntitiesEnvironmentAsync(app.UserTokenCacheInternal, TestConstants.ProductionPrefCacheEnvironment).ConfigureAwait(false); // silent request targeting at, should return at from cache for any environment alias foreach (var envAlias in TestConstants.s_prodEnvAliases) { result = await app .AcquireTokenSilent( TestConstants.s_scope, app.GetAccountsAsync().Result.First()) .WithAuthority(string.Format(CultureInfo.InvariantCulture, "https://{0}/{1}/", envAlias, TestConstants.Utid)) .WithForceRefresh(false) .ExecuteAsync(CancellationToken.None) .ConfigureAwait(false); Assert.IsNotNull(result); } // mock for openId config request for tenant specific authority httpManager.AddMockHandler(new MockHttpMessageHandler { ExpectedUrl = string.Format(CultureInfo.InvariantCulture, "https://{0}/{1}/v2.0/.well-known/openid-configuration", TestConstants.ProductionPrefNetworkEnvironment, TestConstants.Utid), ExpectedMethod = HttpMethod.Get, ResponseMessage = MockHelpers.CreateOpenIdConfigurationResponse(TestConstants.AuthorityUtidTenant) }); // silent request targeting rt should find rt in cache for authority with any environment alias foreach (var envAlias in TestConstants.s_prodEnvAliases) { result = null; httpManager.AddMockHandler(new MockHttpMessageHandler() { ExpectedUrl = string.Format(CultureInfo.InvariantCulture, "https://{0}/{1}/oauth2/v2.0/token", TestConstants.ProductionPrefNetworkEnvironment, TestConstants.Utid), ExpectedMethod = HttpMethod.Post, ExpectedPostData = new Dictionary <string, string>() { { "grant_type", "refresh_token" } }, // return not retriable status code ResponseMessage = MockHelpers.CreateInvalidGrantTokenResponseMessage() }); try { result = await app .AcquireTokenSilent( TestConstants.s_scopeForAnotherResource, (await app.GetAccountsAsync().ConfigureAwait(false)).First()) .WithAuthority(string.Format(CultureInfo.InvariantCulture, "https://{0}/{1}/", envAlias, TestConstants.Utid)) .WithForceRefresh(false) .ExecuteAsync(CancellationToken.None).ConfigureAwait(false); } catch (MsalUiRequiredException) { } catch (Exception) { Assert.Fail(); } Assert.IsNull(result); } } }
public async Task TestSerializationViaAsync() { int numBeforeAccessCalls = 0; int numAfterAccessCalls = 0; int numBeforeWriteCalls = 0; byte[] serializedPayload = null; var sb = new StringBuilder(); using (var harness = CreateTestHarness()) { harness.HttpManager.AddInstanceDiscoveryMockHandler(); PublicClientApplication pca = PublicClientApplicationBuilder .Create(TestConstants.ClientId) .WithAuthority(new Uri(ClientApplicationBase.DefaultAuthority), true) .WithHttpManager(harness.HttpManager) .WithTelemetry(new TraceTelemetryConfig()) .BuildConcrete(); pca.UserTokenCache.SetBeforeAccessAsync(async args => { sb.Append("beforeaccess-"); numBeforeAccessCalls++; // Task Delay is so that we have an await within the async callback and also to simulate // some level of time that we did work. await Task.Delay(10).ConfigureAwait(false); }); pca.UserTokenCache.SetAfterAccessAsync(async args => { sb.Append("afteraccess-"); numAfterAccessCalls++; serializedPayload = args.TokenCache.SerializeMsalV3(); await Task.Delay(10).ConfigureAwait(false); }); pca.UserTokenCache.SetBeforeWriteAsync(async args => { sb.Append("beforewrite-"); numBeforeWriteCalls++; await Task.Delay(10).ConfigureAwait(false); }); MsalMockHelpers.ConfigureMockWebUI( pca.ServiceBundle.PlatformProxy, AuthorizationResult.FromUri(pca.AppConfig.RedirectUri + "?code=some-code")); harness.HttpManager.AddMockHandlerForTenantEndpointDiscovery(TestConstants.AuthorityCommonTenant); harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(TestConstants.AuthorityCommonTenant); AuthenticationResult result = await pca .AcquireTokenInteractive(TestConstants.s_scope) .ExecuteAsync(CancellationToken.None) .ConfigureAwait(false); } Assert.AreEqual("beforeaccess-beforewrite-afteraccess-", sb.ToString()); Assert.AreEqual(1, numBeforeAccessCalls); Assert.AreEqual(1, numAfterAccessCalls); Assert.AreEqual(1, numBeforeWriteCalls); Assert.IsNotNull(serializedPayload); }
public void AuthorityMigration_IntegrationTest() { // make sure that for all network calls "preferred_cache" environment is used // (it is taken from metadata in instance discovery response), // except very first network call - instance discovery using (var httpManager = new MockHttpManager()) { var serviceBundle = ServiceBundle.CreateWithCustomHttpManager(httpManager); TestInitialize(httpManager); PublicClientApplication app = new PublicClientApplication( serviceBundle, MsalTestConstants.ClientId, string.Format( CultureInfo.InvariantCulture, "https://{0}/common", MsalTestConstants.ProductionNotPrefEnvironmentAlias)) { UserTokenCache = { LegacyCachePersistence = new TestLegacyCachePersistance() } }; // mock for openId config request httpManager.AddMockHandler(new MockHttpMessageHandler { Url = string.Format(CultureInfo.InvariantCulture, "https://{0}/common/v2.0/.well-known/openid-configuration", MsalTestConstants.ProductionPrefNetworkEnvironment), Method = HttpMethod.Get, ResponseMessage = MockHelpers.CreateOpenIdConfigurationResponse(MsalTestConstants.AuthorityHomeTenant) }); // mock webUi authorization MsalMockHelpers.ConfigureMockWebUI(new AuthorizationResult(AuthorizationStatus.Success, app.RedirectUri + "?code=some-code"), null, MsalTestConstants.ProductionPrefNetworkEnvironment); // mock token request httpManager.AddMockHandler(new MockHttpMessageHandler { Url = string.Format(CultureInfo.InvariantCulture, "https://{0}/home/oauth2/v2.0/token", MsalTestConstants.ProductionPrefNetworkEnvironment), Method = HttpMethod.Post, ResponseMessage = MockHelpers.CreateSuccessTokenResponseMessage() }); AuthenticationResult result = app.AcquireTokenAsync(MsalTestConstants.Scope).Result; // make sure that all cache entities are stored with "preferred_cache" environment // (it is taken from metadata in instance discovery response) ValidateCacheEntitiesEnvironment(app.UserTokenCache, MsalTestConstants.ProductionPrefCacheEnvironment); // silent request targeting at, should return at from cache for any environment alias foreach (var envAlias in MsalTestConstants.ProdEnvAliases) { result = app.AcquireTokenSilentAsync(MsalTestConstants.Scope, app.GetAccountsAsync().Result.First(), string.Format(CultureInfo.InvariantCulture, "https://{0}/{1}/", envAlias, MsalTestConstants.Utid), false).Result; Assert.IsNotNull(result); } // mock for openId config request for tenant spesific authority httpManager.AddMockHandler(new MockHttpMessageHandler { Url = string.Format(CultureInfo.InvariantCulture, "https://{0}/{1}/v2.0/.well-known/openid-configuration", MsalTestConstants.ProductionPrefNetworkEnvironment, MsalTestConstants.Utid), Method = HttpMethod.Get, ResponseMessage = MockHelpers.CreateOpenIdConfigurationResponse(MsalTestConstants.AuthorityUtidTenant) }); // silent request targeting rt should find rt in cahce for authority with any environment alias foreach (var envAlias in MsalTestConstants.ProdEnvAliases) { httpManager.AddMockHandler(new MockHttpMessageHandler() { Url = string.Format(CultureInfo.InvariantCulture, "https://{0}/{1}/oauth2/v2.0/token", MsalTestConstants.ProductionPrefNetworkEnvironment, MsalTestConstants.Utid), Method = HttpMethod.Post, PostData = new Dictionary <string, string>() { { "grant_type", "refresh_token" } }, // return not retriable status code ResponseMessage = MockHelpers.CreateInvalidGrantTokenResponseMessage() }); try { result = null; result = app.AcquireTokenSilentAsync(MsalTestConstants.ScopeForAnotherResource, app.GetAccountsAsync().Result.First(), string.Format(CultureInfo.InvariantCulture, "https://{0}/{1}/", envAlias, MsalTestConstants.Utid), false).Result; } catch (AggregateException ex) { Assert.IsNotNull(ex.InnerException); Assert.IsTrue(ex.InnerException is MsalUiRequiredException); } Assert.IsNull(result); } } }
public async Task NoCacheLookupAsync() { MyReceiver myReceiver = new MyReceiver(); using (MockHttpAndServiceBundle harness = CreateTestHarness(telemetryCallback: myReceiver.HandleTelemetryEvents)) { TokenCache cache = new TokenCache(harness.ServiceBundle, false); MsalAccessTokenCacheItem atItem = new MsalAccessTokenCacheItem( TestConstants.ProductionPrefNetworkEnvironment, TestConstants.ClientId, TestConstants.s_scope.AsSingleString(), TestConstants.Utid, null, new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(3599)), new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(7200)), MockHelpers.CreateClientInfo()); string atKey = atItem.GetKey().ToString(); atItem.Secret = atKey; ((ITokenCacheInternal)cache).Accessor.SaveAccessToken(atItem); MockWebUI ui = new MockWebUI() { MockResult = AuthorizationResult.FromUri(TestConstants.AuthorityHomeTenant + "?code=some-code") }; MsalMockHelpers.ConfigureMockWebUI(harness.ServiceBundle.PlatformProxy, ui); MockInstanceDiscoveryAndOpenIdRequest(harness.HttpManager); harness.HttpManager.AddSuccessTokenResponseMockHandlerForPost(TestConstants.AuthorityHomeTenant); AuthenticationRequestParameters parameters = harness.CreateAuthenticationRequestParameters( TestConstants.AuthorityHomeTenant, TestConstants.s_scope, cache, extraQueryParameters: new Dictionary <string, string> { { "extra", "qp" } }); parameters.RedirectUri = new Uri("some://uri"); parameters.LoginHint = TestConstants.DisplayableId; AcquireTokenInteractiveParameters interactiveParameters = new AcquireTokenInteractiveParameters { Prompt = Prompt.SelectAccount, ExtraScopesToConsent = TestConstants.s_scopeForAnotherResource.ToArray(), }; InteractiveRequest request = new InteractiveRequest( parameters, interactiveParameters); AuthenticationResult result = await request.RunAsync().ConfigureAwait(false); Assert.AreEqual(1, ((ITokenCacheInternal)cache).Accessor.GetAllRefreshTokens().Count()); Assert.AreEqual(2, ((ITokenCacheInternal)cache).Accessor.GetAllAccessTokens().Count()); Assert.AreEqual(result.AccessToken, "some-access-token"); Assert.IsNotNull( myReceiver.EventsReceived.Find( anEvent => // Expect finding such an event anEvent[EventBase.EventNameKey].EndsWith("ui_event") && anEvent[UiEvent.UserCancelledKey] == "false")); Assert.IsNotNull( myReceiver.EventsReceived.Find( anEvent => // Expect finding such an event anEvent[EventBase.EventNameKey].EndsWith("api_event") && anEvent[ApiEvent.PromptKey] == "select_account")); Assert.IsNotNull( myReceiver.EventsReceived.Find( anEvent => // Expect finding such an event anEvent[EventBase.EventNameKey].EndsWith("ui_event") && anEvent[UiEvent.AccessDeniedKey] == "false")); } }
public async Task VerifyAuthorizationResultTestAsync() { using (MockHttpAndServiceBundle harness = CreateTestHarness()) { MockInstanceDiscoveryAndOpenIdRequest(harness.HttpManager); MockWebUI webUi = new MockWebUI() { MockResult = AuthorizationResult.FromUri(TestConstants.AuthorityHomeTenant + "?error=" + OAuth2Error.LoginRequired), }; MsalMockHelpers.ConfigureMockWebUI(harness.ServiceBundle.PlatformProxy, webUi); AuthenticationRequestParameters parameters = harness.CreateAuthenticationRequestParameters( TestConstants.AuthorityHomeTenant, TestConstants.s_scope, new TokenCache(harness.ServiceBundle, false), extraQueryParameters: new Dictionary <string, string> { { "extra", "qp" } }); parameters.RedirectUri = new Uri("some://uri"); parameters.LoginHint = TestConstants.DisplayableId; AcquireTokenInteractiveParameters interactiveParameters = new AcquireTokenInteractiveParameters { Prompt = Prompt.ForceLogin, ExtraScopesToConsent = TestConstants.s_scopeForAnotherResource.ToArray(), }; InteractiveRequest request = new InteractiveRequest( parameters, interactiveParameters); var ex = await AssertException.TaskThrowsAsync <MsalUiRequiredException>( () => request.RunAsync()) .ConfigureAwait(false); Assert.AreEqual( MsalError.NoPromptFailedError, ex.ErrorCode); Assert.AreEqual( UiRequiredExceptionClassification.PromptNeverFailed, ex.Classification); webUi = new MockWebUI { MockResult = AuthorizationResult.FromUri( TestConstants.AuthorityHomeTenant + "?error=invalid_request&error_description=some error description") }; MsalMockHelpers.ConfigureMockWebUI(harness.ServiceBundle.PlatformProxy, webUi); request = new InteractiveRequest( parameters, interactiveParameters); var ex2 = await AssertException.TaskThrowsAsync <MsalServiceException>( () => request.RunAsync()) .ConfigureAwait(false); Assert.AreEqual("invalid_request", ex2.ErrorCode); Assert.AreEqual("some error description", ex2.Message); } }