private async Task <MsalTokenResponse> AcquireBasicTokenSilentAsync( WebAccount webAccount, string clientId) { // we checked that it exists previously _wamProxy.TryGetAccountProperty(webAccount, "Authority", out string accountAuthority); var provider = await _webAccountProviderFactory.GetAccountProviderAsync(accountAuthority).ConfigureAwait(false); // We are not requesting any additional scopes beyond "profile" and "openid" (which are added by default) // since we do not want to require any additional claims (and thus be unable to renew the refresh token). var request = await CreateWebTokenRequestAsync(provider, clientId, "profile openid").ConfigureAwait(false); // Note that this is never a guest flow, we are always acquiring a token for the home realm, // since we only need the client info. var wamResult = await _wamProxy.GetTokenSilentlyAsync(webAccount, request).ConfigureAwait(false); if (!wamResult.ResponseStatus.IsSuccessStatus()) { _logger.Warning($"[WAM AAD Provider] GetIdFromWebResponseAsync failed {wamResult.ResponseStatus} - {wamResult.ResponseError}"); return(null); } return(ParseSuccessfullWamResponse(wamResult.ResponseData[0], out _)); }
public async Task GetAccounts_WamAccount_NoCacheAccounts_WebRequest_Async() { // Arrange using (MockHttpAndServiceBundle harness = CreateTestHarness()) { const string User1Upn = "*****@*****.**"; var wamAccountProvider = new WebAccountProvider("id", User1Upn, null); _webAccountProviderFactory.GetAccountProviderAsync("organizations").Returns(wamAccountProvider); var wamAccount = new WebAccount(wamAccountProvider, "*****@*****.**", WebAccountState.Connected); _wamProxy.FindAllWebAccountsAsync(wamAccountProvider, TestConstants.ClientId).Returns(new[] { wamAccount }); _wamProxy.TryGetAccountProperty(wamAccount, "Authority", out string _).Returns(x => { x[2] = TestConstants.AuthorityCommonTenant; return(true); }); var rq = new Client.Internal.RequestContext(harness.ServiceBundle, Guid.NewGuid(), default); _cacheSessionManager.RequestContext.Returns(rq); _instanceDiscoveryManager.GetMetadataEntryTryAvoidNetworkAsync( Arg.Any <AuthorityInfo>(), Arg.Any <IEnumerable <string> >(), rq) .Returns(CreateEntryForSingleAuthority(new Uri(TestConstants.AuthorityCommonTenant))); // user set this authority in config // Setup for the silent token request we're going to do via WAM _webAccountProviderFactory.GetAccountProviderAsync(TestConstants.AuthorityCommonTenant).Returns(wamAccountProvider); IWebTokenRequestResultWrapper webTokenResponseWrapper = CreateSuccessResponse(wamAccount); var newlyAddedAccountToCache = new Account("Id_From_ESTS", "upn", null); _wamProxy.GetTokenSilentlyAsync(wamAccount, Arg.Any <WebTokenRequest>()).Returns(webTokenResponseWrapper); _cacheSessionManager.SaveTokenResponseAsync(Arg.Any <MsalTokenResponse>()).Returns(Task.FromResult( new Tuple <MsalAccessTokenCacheItem, MsalIdTokenCacheItem, Account>(null, null, newlyAddedAccountToCache))); // Act var accounts = await _aadPlugin.GetAccountsAsync( TestConstants.ClientId, AuthorityInfo.FromAuthorityUri(TestConstants.AuthorityCommonTenant, true), _cacheSessionManager, _instanceDiscoveryManager).ConfigureAwait(false); // Assert Assert.AreEqual(1, accounts.Count()); Assert.AreEqual("Id_From_ESTS", accounts.Single().HomeAccountId.Identifier); } }
public async Task <MsalTokenResponse> AcquireTokenSilentAsync( AuthenticationRequestParameters authenticationRequestParameters, AcquireTokenSilentParameters acquireTokenSilentParameters) { using (_logger.LogMethodDuration()) { // Important: MSAL will have already resolved the authority by now, // so we are not expecting "common" or "organizations" but a tenanted authority bool isMsa = IsMsaRequest( authenticationRequestParameters.Authority, null, IsMsaPassthrough(authenticationRequestParameters)); IWamPlugin wamPlugin = isMsa ? _msaPlugin : _aadPlugin; WebAccountProvider provider; if (isMsa) { provider = await _webAccountProviderFactory.GetAccountProviderAsync("consumers").ConfigureAwait(false); } else { provider = await _webAccountProviderFactory.GetAccountProviderAsync(authenticationRequestParameters.Authority.AuthorityInfo.CanonicalAuthority) .ConfigureAwait(false); } WebAccount webAccount = await FindWamAccountForMsalAccountAsync( provider, wamPlugin, authenticationRequestParameters.Account, null, // ATS requires an account object, login_hint is not supported on its own authenticationRequestParameters.ClientId).ConfigureAwait(false); if (webAccount == null) { throw new MsalUiRequiredException( MsalError.InteractionRequired, "Could not find a WAM account for the silent request."); } WebTokenRequest webTokenRequest = await wamPlugin.CreateWebTokenRequestAsync( provider, authenticationRequestParameters, isForceLoginPrompt : false, isAccountInWam : true, isInteractive : false) .ConfigureAwait(false); AddCommonParamsToRequest(authenticationRequestParameters, webTokenRequest); var wamResult = await _wamProxy.GetTokenSilentlyAsync(webAccount, webTokenRequest).ConfigureAwait(false); return(CreateMsalTokenResponse(wamResult, wamPlugin, isInteractive: false)); } }
public async Task ATS_AccountWithWamId_Async() { // Arrange using (MockHttpAndServiceBundle harness = CreateTestHarness()) { _webAccountProviderFactory.ClearReceivedCalls(); var wamAccountProvider = new WebAccountProvider("id", "*****@*****.**", null); var extraQP = new Dictionary <string, string>() { { "extraQp1", "extraVal1" }, { "instance_aware", "true" } }; var requestParams = harness.CreateAuthenticationRequestParameters( TestConstants.AuthorityHomeTenant, extraQueryParameters: extraQP, validateAuthority: true); // AAD requestParams.UserConfiguredAuthority = Authority.CreateAuthority("https://login.microsoftonline.com/organizations"); requestParams.Account = new Account( $"{TestConstants.Uid}.{TestConstants.Utid}", TestConstants.DisplayableId, null, new Dictionary <string, string>() { { TestConstants.ClientId, "wam_id_1" } }); // account has wam_id! var webAccount = new WebAccount(wamAccountProvider, "*****@*****.**", WebAccountState.Connected); var webTokenRequest = new WebTokenRequest(wamAccountProvider); var webTokenResponseWrapper = Substitute.For <IWebTokenRequestResultWrapper>(); webTokenResponseWrapper.ResponseStatus.Returns(WebTokenRequestStatus.Success); var webTokenResponse = new WebTokenResponse(); webTokenResponseWrapper.ResponseData.Returns(new List <WebTokenResponse>() { webTokenResponse }); _webAccountProviderFactory.GetAccountProviderAsync(null).ReturnsForAnyArgs(Task.FromResult(wamAccountProvider)); _wamProxy.FindAccountAsync(Arg.Any <WebAccountProvider>(), "wam_id_1").Returns(Task.FromResult(webAccount)); _aadPlugin.CreateWebTokenRequestAsync( wamAccountProvider, requestParams, isForceLoginPrompt: false, isAccountInWam: true, isInteractive: false) .Returns(Task.FromResult(webTokenRequest)); var atsParams = new AcquireTokenSilentParameters(); _wamProxy.GetTokenSilentlyAsync(webAccount, webTokenRequest). Returns(Task.FromResult(webTokenResponseWrapper)); _aadPlugin.ParseSuccesfullWamResponse(webTokenResponse).Returns(_msalTokenResponse); // Act var result = await _wamBroker.AcquireTokenSilentAsync(requestParams, atsParams).ConfigureAwait(false); // Assert Assert.AreSame(_msalTokenResponse, result); Assert.AreEqual("yes", webTokenRequest.Properties["validateAuthority"]); Assert.AreEqual("extraVal1", webTokenRequest.Properties["extraQp1"]); // Although at the time of writing, MSAL does not support instance aware ... // WAM does support it but the param is different - discovery=home Assert.AreEqual("home", webTokenRequest.Properties["discover"]); Assert.AreEqual("https://login.microsoftonline.com/organizations/", webTokenRequest.Properties["authority"]); } }
public async Task <MsalTokenResponse> AcquireTokenSilentAsync( AuthenticationRequestParameters authenticationRequestParameters, AcquireTokenSilentParameters acquireTokenSilentParameters) { using (_logger.LogMethodDuration()) { // Important: MSAL will have already resolved the authority by now, // so we are not expecting "common" or "organizations" but a tenanted authority bool isMsa = await IsMsaRequestAsync( authenticationRequestParameters.Authority, null, _wamOptions.MsaPassthrough) .ConfigureAwait(false); IWamPlugin wamPlugin = isMsa ? _msaPlugin : _aadPlugin; WebAccountProvider provider; if (_wamOptions.MsaPassthrough) { provider = await GetProviderAsync( "organizations", false).ConfigureAwait(false); } else { provider = await GetProviderAsync( authenticationRequestParameters.AuthorityInfo.CanonicalAuthority, isMsa).ConfigureAwait(false); } WebAccount webAccount = await FindWamAccountForMsalAccountAsync( provider, wamPlugin, authenticationRequestParameters.Account, null, // ATS requires an account object, login_hint is not supported on its own authenticationRequestParameters.AppConfig.ClientId).ConfigureAwait(false); if (webAccount == null && _wamOptions.MsaPassthrough) { return(await AcquireMsaTokenSilentForPassthroughAsync( authenticationRequestParameters, provider).ConfigureAwait(false)); } if (webAccount == null) { throw new MsalUiRequiredException( MsalError.InteractionRequired, "Could not find a WAM account for the silent request."); } WebTokenRequest webTokenRequest = await wamPlugin.CreateWebTokenRequestAsync( provider, authenticationRequestParameters, isForceLoginPrompt : false, isAccountInWam : true, isInteractive : false) .ConfigureAwait(false); // For MSA-PT scenario, MSAL's authority is wrong. MSAL will use Account.HomeTenantId // which will essentialyl be /consumers. This is wrong, we are not trying to obtain // an MSA token, we are trying to obtain an ADD *guest* token. string differentAuthority = null; if (_wamOptions.MsaPassthrough && authenticationRequestParameters.Authority is AadAuthority aadAuthority && aadAuthority.IsConsumers()) { differentAuthority = authenticationRequestParameters.Authority.GetTenantedAuthority("organizations", forceTenantless: true); } WamAdapters.AddMsalParamsToRequest(authenticationRequestParameters, webTokenRequest, _logger, differentAuthority); var wamResult = await _wamProxy.GetTokenSilentlyAsync(webAccount, webTokenRequest).ConfigureAwait(false); return(WamAdapters.CreateMsalResponseFromWamResponse( wamResult, wamPlugin, authenticationRequestParameters.AppConfig.ClientId, _logger, isInteractive: false)); } }