Example #1
0
        private async Task <string?> GetTokenForWebApiToCallDownstreamApiAsync(
            IConfidentialClientApplication application,
            string authority,
            IEnumerable <string> scopes)
        {
            try
            {
                // In web API, validatedToken will not be null
                JwtSecurityToken?validatedToken = CurrentHttpContext?.GetTokenUsedToCallWebAPI();

                // Case of web APIs: we need to do an on-behalf-of flow, with the token used to call the API
                if (validatedToken != null)
                {
                    // In the case the token is a JWE (encrypted token), we use the decrypted token.
                    string tokenUsedToCallTheWebApi = validatedToken.InnerToken == null ? validatedToken.RawData
                                                : validatedToken.InnerToken.RawData;
                    var result = await application
                                 .AcquireTokenOnBehalfOf(scopes.Except(_scopesRequestedByMsal), new UserAssertion(tokenUsedToCallTheWebApi))
                                 .WithSendX5C(_microsoftIdentityOptions.SendX5C)
                                 .WithAuthority(authority)
                                 .ExecuteAsync()
                                 .ConfigureAwait(false);

                    return(result.AccessToken);
                }

                return(null);
            }
            catch (MsalUiRequiredException ex)
            {
                _logger.LogInformation(string.Format(CultureInfo.InvariantCulture, LogMessages.ErrorAcquiringTokenForDownstreamWebApi, ex.Message));
                throw ex;
            }
        }
        public async Task <IActionResult> GetAsync([FromHeader] string authorization)
        {
            string sso_token = authorization.Substring("Bearer".Length + 1);

            IConfidentialClientApplication app = ConfidentialClientApplicationBuilder
                                                 .Create(this.azureADOptions.Value.AppId)
                                                 .WithClientSecret(this.azureADOptions.Value.AppPassword)
                                                 .WithTenantId(this.azureADOptions.Value.TenantId)
                                                 .WithAuthority($"https://login.microsoftonline.com/{this.azureADOptions.Value.TenantId}")
                                                 .Build();

            try
            {
                var onBehalfOfToken = await app.AcquireTokenOnBehalfOf(new List <string>() { "User.ReadBasic.All" }, new UserAssertion(sso_token)).ExecuteAsync();

                return(this.Ok(onBehalfOfToken.AccessToken));
            }
            catch (MsalUiRequiredException e)
            {
                string failureReason = "Failed to retrieve a Graph token for the user";
                if (e.Classification == UiRequiredExceptionClassification.ConsentRequired)
                {
                    failureReason = "The user or admin has not provided sufficient consent for the application";
                }

                return(this.StatusCode(403, new UnsuccessfulResponse {
                    Reason = failureReason
                }));
            }
        }
Example #3
0
        public async Task <AuthenticationResult> GenerateToken(OnBehalfOptions options)
        {
            AuthenticationResult result = null;

            try
            {
                X509Certificate2 certificate       = this._certReader.ReadCertificate(options.CertThumbprint);
                IConfidentialClientApplication app = ConfidentialClientApplicationBuilder.Create(options.ClientId)
                                                     .WithAuthority(new Uri(options.Authority), true)
                                                     .WithCertificate(certificate)
                                                     .Build();
                var userAssertion = new UserAssertion(
                    options.AccessToken,
                    "urn:ietf:params:oauth:grant-type:jwt-bearer");
                result = await app.AcquireTokenOnBehalfOf(new string[] { options.Scope }, userAssertion).ExecuteAsync();
            }
            catch (MsalUiRequiredException ex)
            {
                var message = @"The application doesn't have sufficient permissions.
                - Did you declare enough app permissions during app creation?
                 -Did the tenant admin grant permissions to the application?";
                Console.WriteLine(message);
                Console.WriteLine(ex);
            }
            catch (MsalServiceException ex) when(ex.Message.Contains("AADSTS70011"))
            {
                var message = @"Invalid scope. The scope has to be in the form 'https://resourceurl/.default'
                 Mitigation: Change the scope to be as expected.";

                Console.WriteLine(message);
                Console.WriteLine(ex);
            }

            return(result);
        }
        /// <summary>
        /// Get token using client credentials flow
        /// </summary>
        /// <param name="configuration">IConfiguration instance.</param>
        /// <param name="httpClientFactory">IHttpClientFactory instance.</param>
        /// <param name="httpContextAccessor">IHttpContextAccessor instance.</param>
        /// <returns>App access token on behalf of user.</returns>
        public static async Task <string> GetAccessTokenOnBehalfUserAsync(IConfiguration configuration, IHttpClientFactory httpClientFactory, IHttpContextAccessor httpContextAccessor)
        {
            var tenantId = configuration["AzureAd:TenantId"];
            IConfidentialClientApplication app = ConfidentialClientApplicationBuilder.Create(configuration["AzureAd:MicrosoftAppId"])
                                                 .WithClientSecret(configuration["AzureAd:MicrosoftAppPassword"])
                                                 .WithAuthority($"https://login.microsoftonline.com/{tenantId}")
                                                 .Build();

            try
            {
                var httpContext = httpContextAccessor.HttpContext;
                httpContext.Request.Headers.TryGetValue("Authorization", out StringValues assertion);
                var           idToken = assertion.ToString().Split(" ")[1];
                UserAssertion assert  = new UserAssertion(idToken);
                List <string> scopes  = new List <string>();
                scopes.Add("https://graph.microsoft.com/User.Read");
                var responseToken = await app.AcquireTokenOnBehalfOf(scopes, assert).ExecuteAsync();

                return(responseToken.AccessToken.ToString());
            }
            catch (Exception ex)
            {
                return(ex.Message);
            }
        }
        /// <summary>
        /// Retrieved the access token based on the permission level given to the respective application
        /// </summary>
        /// <param name="app"></param>
        /// <returns></returns>
        protected async Task <string> GetAccessToken(IConfidentialClientApplication app)
        {
            string[]             scopes        = { "user.read.all" };
            UserAssertion        userAssertion = new UserAssertion(BearerToken, "urn:ietf:params:oauth:grant-type:jwt-bearer");
            AuthenticationResult result        = await app.AcquireTokenOnBehalfOf(scopes, userAssertion).ExecuteAsync();

            return(result.AccessToken);
        }
Example #6
0
        public async Task <string> GetAccessToken()
        {
            try
            {
                // First attempt to get token from the cache for this user
                // Check for a matching account in the cache
                var account = await _msalClient.GetAccountAsync(_tokenResult.MsalAccountId);

                if (account != null)
                {
                    // Make a "silent" request for a token. This will
                    // return the cached token if still valid, and will handle
                    // refreshing the token if needed
                    var cacheResult = await _msalClient
                                      .AcquireTokenSilent(_scopes, account)
                                      .ExecuteAsync();

                    _logger.LogInformation($"User access token: {cacheResult.AccessToken}");
                    return(cacheResult.AccessToken);
                }
            }
            catch (MsalUiRequiredException)
            {
                // This exception indicates that a new token
                // can only be obtained by invoking the on-behalf-of
                // flow. "UiRequired" isn't really accurate since the OBO
                // flow doesn't involve UI.
                // Catching the exception so code will continue to the
                // AcquireTokenOnBehalfOf call below.
            }
            catch (Exception exception)
            {
                _logger.LogError(exception, "Error getting access token via on-behalf-of flow");
                return(null);
            }

            try
            {
                _logger.LogInformation("Token not found in cache, attempting OBO flow");

                // Use the token sent by the calling client as a
                // user assertion
                var userAssertion = new UserAssertion(_tokenResult.Token);

                // Invoke on-behalf-of flow
                var result = await _msalClient
                             .AcquireTokenOnBehalfOf(_scopes, userAssertion)
                             .ExecuteAsync();

                _logger.LogInformation($"User access token: {result.AccessToken}");
                return(result.AccessToken);
            }
            catch (Exception exception)
            {
                _logger.LogError(exception, "Error getting access token from cache");
                return(null);
            }
        }
        /// <summary>
        /// Typically used from a Web App or WebAPI controller, this method retrieves an access token
        /// for a downstream API using;
        /// 1) the token cache (for Web Apps and Web APis) if a token exists in the cache
        /// 2) or the <a href='https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow'>on-behalf-of flow</a>
        /// in Web APIs, for the user account that is ascertained from claims are provided in the <see cref="HttpContext.User"/>
        /// instance of the current HttpContext.
        /// </summary>
        /// <param name="scopes">Scopes to request for the downstream API to call.</param>
        /// <param name="tenant">Enables overriding of the tenant/account for the same identity. This is useful in the
        /// cases where a given account is guest in other tenants, and you want to acquire tokens for a specific tenant, like where the user is a guest in.</param>
        /// <returns>An access token to call the downstream API and populated with this downstream Api's scopes.</returns>
        /// <remarks>Calling this method from a Web API supposes that you have previously called,
        /// in a method called by JwtBearerOptions.Events.OnTokenValidated, the HttpContextExtensions.StoreTokenUsedToCallWebAPI method
        /// passing the validated token (as a JwtSecurityToken). Calling it from a Web App supposes that
        /// you have previously called AddAccountToCacheFromAuthorizationCodeAsync from a method called by
        /// OpenIdConnectOptions.Events.OnAuthorizationCodeReceived.</remarks>
        public async Task <string> GetAccessTokenForUserAsync(
            IEnumerable <string> scopes,
            string tenant = null)
        {
            if (scopes == null)
            {
                throw new ArgumentNullException(nameof(scopes));
            }

            // Use MSAL to get the right token to call the API
            _application = await GetOrBuildConfidentialClientApplicationAsync().ConfigureAwait(false);

            string accessToken;

            try
            {
                accessToken = await GetAccessTokenOnBehalfOfUserFromCacheAsync(_application, CurrentHttpContext.User, scopes, tenant)
                              .ConfigureAwait(false);
            }
            catch (MsalUiRequiredException ex)
            {
                // GetAccessTokenForUserAsync is an abstraction that can be called from a Web App or a Web API
                _logger.LogInformation(ex.Message);

                // to get a token for a Web API on behalf of the user, but not necessarily with the on behalf of OAuth2.0
                // flow as this one only applies to Web APIs.
                JwtSecurityToken validatedToken = CurrentHttpContext.GetTokenUsedToCallWebAPI();

                // Case of Web APIs: we need to do an on-behalf-of flow
                if (validatedToken != null)
                {
                    // In the case the token is a JWE (encrypted token), we use the decrypted token.
                    string tokenUsedToCallTheWebApi = validatedToken.InnerToken == null ? validatedToken.RawData
                                                : validatedToken.InnerToken.RawData;
                    var result = await _application
                                 .AcquireTokenOnBehalfOf(scopes.Except(_scopesRequestedByMsal),
                                                         new UserAssertion(tokenUsedToCallTheWebApi))
                                 .ExecuteAsync()
                                 .ConfigureAwait(false);

                    accessToken = result.AccessToken;
                }

                // Case of the Web App: we let the MsalUiRequiredException be caught by the
                // AuthorizeForScopesAttribute exception filter so that the user can consent, do 2FA, etc ...
                else
                {
                    throw;
                }
            }

            return(accessToken);
        }
        public HttpResponseMessage Token(Token body)
        {
            if (string.IsNullOrEmpty(body.UserToken))
            {
                return(SendErrorToClient(HttpStatusCode.InternalServerError, null, "No token provided"));
            }

            UserAssertion userAssertion = new UserAssertion(body.UserToken);

            // Get the access token for MS Graph.
            ConfidentialClientApplicationBuilder b = ConfidentialClientApplicationBuilder.Create(ConfigurationManager.AppSettings["ida:ClientID"]);

            b.WithClientSecret(ConfigurationManager.AppSettings["ida:Password"]).WithRedirectUri(ConfigurationManager.AppSettings["ida:RedirectUri"]);
            IConfidentialClientApplication cca = b.Build();

            //string[] graphScopes = { "user.read", "files.read.all", "mail.read", "calendars.read" };

            string[] graphScopes = { "Mail.Read", "Files.Read.All", "Calendars.Read" };

            AuthenticationResult result = null;

            try
            {
                // The AcquireTokenOnBehalfOfAsync method will first look in the MSAL in memory cache for a
                // matching access token. Only if there isn't one, does it initiate the "on behalf of" flow
                // with the Azure AD V2 endpoint.
                result = cca.AcquireTokenOnBehalfOf(graphScopes, userAssertion).ExecuteAsync().Result;
            }
            catch (MsalServiceException e)
            {
                if (e.Message.StartsWith("AADSTS50076"))
                {
                    string responseMessage = String.Format("{{\"AADError\":\"AADSTS50076\",\"Claims\":{0}}}", e.Claims);
                    return(SendErrorToClient(HttpStatusCode.InternalServerError, e, responseMessage));
                }

                if ((e.Message.StartsWith("AADSTS65001")) ||
                    (e.Message.StartsWith("AADSTS70011: The provided value for the input parameter 'scope' is not valid.")))
                {
                    return(SendErrorToClient(HttpStatusCode.InternalServerError, e, e.Message));
                }

                return(SendErrorToClient(HttpStatusCode.InternalServerError, e, e.Message));
            }

            HttpRequestMessage requestMessage = new HttpRequestMessage();
            var configuration = new HttpConfiguration();

            requestMessage.Properties[System.Web.Http.Hosting.HttpPropertyKeys.HttpConfigurationKey] = configuration;
            HttpResponseMessage tokenMessage = requestMessage.CreateResponse(HttpStatusCode.OK, result.AccessToken);

            return(tokenMessage);
        }
Example #9
0
        private async Task <AuthenticationResult?> GetAuthenticationResultForWebApiToCallDownstreamApiAsync(
            IConfidentialClientApplication application,
            string authority,
            IEnumerable <string> scopes,
            TokenAcquisitionOptions?tokenAcquisitionOptions)
        {
            try
            {
                // In web API, validatedToken will not be null
                JwtSecurityToken?validatedToken = CurrentHttpContext?.GetTokenUsedToCallWebAPI();

                // Case of web APIs: we need to do an on-behalf-of flow, with the token used to call the API
                if (validatedToken != null)
                {
                    // In the case the token is a JWE (encrypted token), we use the decrypted token.
                    string tokenUsedToCallTheWebApi = validatedToken.InnerToken == null ? validatedToken.RawData
                                                : validatedToken.InnerToken.RawData;
                    var builder = application
                                  .AcquireTokenOnBehalfOf(
                        scopes.Except(_scopesRequestedByMsal),
                        new UserAssertion(tokenUsedToCallTheWebApi))
                                  .WithSendX5C(_microsoftIdentityOptions.SendX5C)
                                  .WithAuthority(authority);

                    if (tokenAcquisitionOptions != null)
                    {
                        builder.WithExtraQueryParameters(tokenAcquisitionOptions.ExtraQueryParameters);
                        builder.WithCorrelationId(tokenAcquisitionOptions.CorrelationId);
                        builder.WithForceRefresh(tokenAcquisitionOptions.ForceRefresh);
                        builder.WithClaims(tokenAcquisitionOptions.Claims);
                        if (tokenAcquisitionOptions.PoPConfiguration != null)
                        {
                            builder.WithProofOfPossession(tokenAcquisitionOptions.PoPConfiguration);
                        }
                    }

                    return(await builder.ExecuteAsync()
                           .ConfigureAwait(false));
                }

                return(null);
            }
            catch (MsalUiRequiredException ex)
            {
                _logger.LogInformation(
                    string.Format(
                        CultureInfo.InvariantCulture,
                        LogMessages.ErrorAcquiringTokenForDownstreamWebApi,
                        ex.Message));
                throw;
            }
        }
Example #10
0
        public override async Task <AuthenticationResult> TokenForCurrentUser(string[] scopes)
        {
            if (accessor.HttpContext.Request.Headers.TryGetValue("Authorization",
                                                                 out Microsoft.Extensions.Primitives.StringValues value))
            {
                var token = value.FirstOrDefault();

                AzureAdOptions o = options.Value;

                IConfidentialClientApplication app = ConfidentialClientApplicationBuilder.Create(clientId: o.ClientId)
                                                     .WithClientSecret(o.ClientSecret)
                                                     .WithTenantId(o.TenantId)
                                                     .Build();

                AuthenticationResult t =
                    await app.AcquireTokenOnBehalfOf(scopes, new UserAssertion(token.Split(" ")[1])).ExecuteAsync();

                return(t);
            }
            else
            {
                ClaimsPrincipal user = accessor.HttpContext.User;
                if (user == null || !user.Identity.IsAuthenticated)
                {
                    throw new ForbiddenException("Not authenticated");
                }

                try
                {
                    AuthenticationResult result = await tokenService.GetAccessTokenAsync(user, scopes);

                    return(result);
                }
                catch (MsalUiRequiredException e)
                {
                    if (e.Classification == UiRequiredExceptionClassification.ConsentRequired)
                    {
                        var message =
                            $"Consent missing: The app does not yet have your consent to the scope '{scopes[0]}'." +
                            $" Please first allow the app to act on your behalf, then try again." +
                            $" Scopes can be granted under the account settings.";
                        logger.LogError("Missing consent {@scopes}", scopes);
                        throw new MissingConsentException(message, scopes[0]);
                    }

                    throw;
                }
            }
        }
Example #11
0
        public async Task <string> GetUserAccessTokenAsync(string jwtBearerToken)
        {
            var account = await _oboApp.AcquireTokenOnBehalfOf(_scopes, new UserAssertion(jwtBearerToken)).ExecuteAsync();

            if (account == null)
            {
                throw new ServiceException(new Error
                {
                    Code    = "TokenNotFound",
                    Message = "Unable to retrieve the access token from assertion"
                });
            }

            return(account.AccessToken);
        }
Example #12
0
        public void EnsurePublicApiSurfaceExistsOnInterface()
        {
            IConfidentialClientApplication app = ConfidentialClientApplicationBuilder.Create(TestConstants.ClientId)
                                                 .WithClientSecret("cats")
                                                 .Build();

            // This test is to ensure that the methods we want/need on the IConfidentialClientApplication exist and compile.  This isn't testing functionality, that's done elsewhere.
            // It's solely to ensure we know that the methods we want/need are available where we expect them since we tend to do most testing on the concrete types.

            var authCodeBuilder = app.AcquireTokenByAuthorizationCode(TestConstants.s_scope, "authorizationcode");

            PublicClientApplicationTests.CheckBuilderCommonMethods(authCodeBuilder);

            var clientBuilder = app.AcquireTokenForClient(TestConstants.s_scope)
                                .WithForceRefresh(true)
                                .WithSendX5C(true);

            PublicClientApplicationTests.CheckBuilderCommonMethods(clientBuilder);

            var onBehalfOfBuilder = app.AcquireTokenOnBehalfOf(
                TestConstants.s_scope,
                new UserAssertion("assertion", "assertiontype"))
                                    .WithSendX5C(true);

            PublicClientApplicationTests.CheckBuilderCommonMethods(onBehalfOfBuilder);

            var silentBuilder = app.AcquireTokenSilent(TestConstants.s_scope, "*****@*****.**")
                                .WithForceRefresh(false);

            PublicClientApplicationTests.CheckBuilderCommonMethods(silentBuilder);

            silentBuilder = app.AcquireTokenSilent(TestConstants.s_scope, TestConstants.s_user)
                            .WithForceRefresh(true);
            PublicClientApplicationTests.CheckBuilderCommonMethods(silentBuilder);

            var requestUrlBuilder = app.GetAuthorizationRequestUrl(TestConstants.s_scope)
                                    .WithAccount(TestConstants.s_user)
                                    .WithLoginHint("loginhint")
                                    .WithExtraScopesToConsent(TestConstants.s_scope)
                                    .WithRedirectUri(TestConstants.RedirectUri);

            PublicClientApplicationTests.CheckBuilderCommonMethods(requestUrlBuilder);

            var byRefreshTokenBuilder = ((IByRefreshToken)app).AcquireTokenByRefreshToken(TestConstants.s_scope, "refreshtoken")
                                        .WithRefreshToken("refreshtoken");

            PublicClientApplicationTests.CheckBuilderCommonMethods(byRefreshTokenBuilder);
        }
Example #13
0
        /// <summary>
        /// Gets an access token for the requested resource and scope
        /// </summary>
        /// <param name="resource">Resource to request an access token for (unused)</param>
        /// <param name="scopes">Scopes to request</param>
        /// <returns>An access token</returns>
        public override async Task <string> GetAccessTokenAsync(Uri resource, string[] scopes)
        {
            if (resource == null)
            {
                throw new ArgumentNullException(nameof(resource));
            }

            if (scopes == null)
            {
                throw new ArgumentNullException(nameof(scopes));
            }

            if (UserTokenProvider == null)
            {
                throw new ConfigurationErrorsException(
                          PnPCoreAuthResources.OnBehalfOfAuthenticationProvider_MissingUserTokenProvider);
            }

            AuthenticationResult tokenResult = null;

            try
            {
                // Define the user assertion based on the consumer access token
                var assertion = new UserAssertion(UserTokenProvider.Invoke());

                // Try to get the token from the tokens cache
                tokenResult = await confidentialClientApplication
                              .AcquireTokenOnBehalfOf(scopes, assertion)
                              .ExecuteAsync().ConfigureAwait(false);
            }
            catch (MsalServiceException)
            {
                // Handle the various exceptions
                throw;
            }

            // Log the access token retrieval action
            Log?.LogInformation(PnPCoreAuthResources.AuthenticationProvider_LogAccessTokenRetrieval,
                                GetType().Name, resource, scopes.Aggregate(string.Empty, (c, n) => c + ", " + n).TrimEnd(','));

            // Return the Access Token, if we've got it
            // In case of any exception while retrieving the access token,
            // MSAL will throw an exception that we simply bubble up
            return(tokenResult.AccessToken);
        }
Example #14
0
        /// <summary>
        /// For web APIs, acquire token on-behalf-of flow with the token used to call the API
        /// </summary>
        /// <param name="requestedScopes"></param>
        /// <returns></returns>
        public async Task <AuthenticationResult> GetUserTokenOnBehalfOfAsync(IEnumerable <string> requestedScopes)
        {
            string authority = $"{AuthenticationConfig.AADInstance}{AuthenticationConfig.TenantId}/";

            this.PrepareConfidentialClientInstanceAsync();

            //IConfidentialClientApplication app = await BuildConfidentialClientApplicationAsync();

            var bootstrapContext = ClaimsPrincipal.Current.Identities.First().BootstrapContext;

            string        userAccessToken = (string)bootstrapContext;
            UserAssertion userAssertion   = new UserAssertion(userAccessToken, "urn:ietf:params:oauth:grant-type:jwt-bearer");
            var           result          = await _application.AcquireTokenOnBehalfOf(requestedScopes, userAssertion)
                                            .WithAuthority(authority)
                                            .ExecuteAsync();

            return(result);
        }
Example #15
0
        public async Task <IActionResult> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req)
        {
            var accessTokenForThis = req.Headers["Authorization"].ToString().Split(" ")[1];

            _log.LogTrace("Got access token from header, using that in assertion");
            _log.LogTrace(accessTokenForThis);
            var tokenRequest = _aadApp.AcquireTokenOnBehalfOf(_scopes.Split(" "), new UserAssertion(accessTokenForThis));
            var token        = await tokenRequest.ExecuteAsync();

            _log.LogTrace($"Got new access token obo: {token.AccessToken}");

            _httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token.AccessToken);
            var ping = await _httpClient.GetAsync(_apiUrl);

            if (ping.IsSuccessStatusCode)
            {
                return(new OkObjectResult(new { data = await ping.Content.ReadAsStringAsync() }));
            }
            return(new BadRequestObjectResult(new { data = ping.StatusCode, message = ping.ReasonPhrase }));
        }
Example #16
0
        public async Task <IActionResult> GetAsync([FromHeader] string authorization)
        {
            string sso_token = authorization.Substring("Bearer".Length + 1);

            IConfidentialClientApplication app = ConfidentialClientApplicationBuilder
                                                 .Create(this.azureADOptions.Value.AppId)
                                                 .WithClientSecret(this.azureADOptions.Value.AppPassword)
                                                 .WithTenantId(this.azureADOptions.Value.TenantId)
                                                 .WithAuthority($"https://login.microsoftonline.com/{this.azureADOptions.Value.TenantId}")
                                                 .Build();

            try
            {
                var onBehalfOfToken = await app.AcquireTokenOnBehalfOf(new List <string>() { "ChannelMessage.Send", "User.ReadBasic.All" }, new UserAssertion(sso_token)).ExecuteAsync();

                return(this.Ok(onBehalfOfToken.AccessToken));
            }
            catch (MsalUiRequiredException)
            {
                return(this.StatusCode(403));
            }
        }
Example #17
0
        public async Task <string> Get(
            bool ccaPerRequest = true,
            Flow flow          = Flow.S2S,
            int userForObo     = 1,
            TID tenantId       = TID.A,
            Scope scope        = Scope.S1,
            bool staticL1      = false,
            bool useL2         = true)
        {
            char c   = tenantId.ToString().ToCharArray()[0];
            var  tid = new string(Enumerable.Repeat(c, 16).ToArray());

            IConfidentialClientApplication cca = GetOrCreateCCA(ccaPerRequest, staticL1, useL2);

            AuthenticationResult res;

            if (flow == Flow.S2S)
            {
                res = await cca.AcquireTokenForClient(new[] { scope.ToString() })
                      .WithAuthority($"https://login.microsoftonline.com/{tid}")
                      .ExecuteAsync().ConfigureAwait(false);
            }
            else
            {
                var user = $"user_{userForObo}";

                // must be in this format. MSAL will use {user} as the object id
                string fakeUpstreamToken = $"upstream_token_{user}";

                res = await cca.AcquireTokenOnBehalfOf(new[] { scope.ToString() }, new UserAssertion(fakeUpstreamToken))
                      .WithAuthority($"https://login.microsoftonline.com/{tid}")
                      .ExecuteAsync()
                      .ConfigureAwait(false);
            }



            return(res.AuthenticationResultMetadata.TokenSource.ToString());
        }
Example #18
0
            public override async ValueTask <AccessToken> GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken)
            {
                AuthenticationResult result = await _confidentialClient.AcquireTokenOnBehalfOf(requestContext.Scopes, _userAssertion).ExecuteAsync();

                return(new AccessToken(result.AccessToken, result.ExpiresOn));
            }
        public async Task <string> GetAccessTokenForUserAsync(HttpRequestData req, IEnumerable <string> scopes, string?tenantId = null, string?userFlow = null)
        {
            var result = await _application.AcquireTokenOnBehalfOf(scopes, new UserAssertion(getAccessTokenFromHeaders(req))).ExecuteAsync();

            return(result.AccessToken);
        }