// GET: Makes a call to the API and retrieves the list of tasks
        public async Task <ActionResult> Index()
        {
            try
            {
                // Retrieve the token with the specified scopes
                var scope = new string[] { Globals.ReadTasksScope };

                IConfidentialClientApplication cca = MsalAppBuilder.BuildConfidentialClientApplication();
                var accounts = await cca.GetAccountsAsync();

                AuthenticationResult result = await cca.AcquireTokenSilent(scope, accounts.FirstOrDefault()).ExecuteAsync();

                HttpClient         client  = new HttpClient();
                HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, apiEndpoint);

                // Add token to the Authorization header and make the request
                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
                HttpResponseMessage response = await client.SendAsync(request);

                // Handle the response
                switch (response.StatusCode)
                {
                case HttpStatusCode.OK:
                    string responseString = await response.Content.ReadAsStringAsync();

                    JArray tasks = JArray.Parse(responseString);
                    ViewBag.Tasks = tasks;
                    return(View());

                case HttpStatusCode.Unauthorized:
                    return(ErrorAction("Please sign in again. " + response.ReasonPhrase));

                default:
                    return(ErrorAction("Error. Status code = " + response.StatusCode + ": " + response.ReasonPhrase));
                }
            }
            catch (MsalUiRequiredException ex)
            {
                /*
                 * If the tokens have expired or become invalid for any reason, ask the user to sign in again.
                 * Another cause of this exception is when you restart the app using InMemory cache.
                 * It will get wiped out while the user will be authenticated still because of their cookies, requiring the TokenCache to be initialized again
                 * through the sign in flow.
                 */
                return(new RedirectResult("/Account/SignUpSignIn?redirectUrl=/Tasks"));
            }
            catch (Exception ex)
            {
                return(ErrorAction("Error reading to do list: " + ex.Message));
            }
        }
Ejemplo n.º 2
0
        public async Task <IActionResult> Api()
        {
            string responseString;

            try
            {
                // Retrieve the token with the specified scopes
                var    scope          = AzureAdB2COptions.ApiScopes.Split(' ');
                string signedInUserID = HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value;

                IConfidentialClientApplication cca =
                    ConfidentialClientApplicationBuilder.Create(AzureAdB2COptions.ClientId)
                    .WithRedirectUri(AzureAdB2COptions.RedirectUri)
                    .WithClientSecret(AzureAdB2COptions.ClientSecret)
                    .WithB2CAuthority(AzureAdB2COptions.Authority)
                    .Build();
                new MSALStaticCache(signedInUserID).EnablePersistence(cca.UserTokenCache);

                var accounts = await cca.GetAccountsAsync();

                AuthenticationResult result = await cca.AcquireTokenSilent(scope, accounts.FirstOrDefault())
                                              .ExecuteAsync();

                HttpClient         client  = new HttpClient();
                HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, AzureAdB2COptions.ApiUrl);

                // Add token to the Authorization header and make the request
                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
                HttpResponseMessage response = await client.SendAsync(request);

                // Handle the response
                responseString = response.StatusCode switch
                {
                    HttpStatusCode.OK => (await response.Content.ReadAsStringAsync()).Replace("},", $"}}, {Environment.NewLine}"),
                    HttpStatusCode.Unauthorized => $"Please sign in again.{Environment.NewLine} {response.ReasonPhrase}",
                    _ => $"Error calling API.{Environment.NewLine} StatusCode=${response.StatusCode}",
                };
            }
            catch (MsalUiRequiredException ex)
            {
                responseString = $"Session has expired. Please sign in again.{Environment.NewLine} {ex.Message}";
            }
            catch (Exception ex)
            {
                responseString = $"Error calling API:{Environment.NewLine} {ex.Message}";
            }

            ViewData["Payload"] = $"{responseString}";
            return(View());
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Gets an access token from cache on behalf of the user.
        /// </summary>
        /// <param name="application"></param>
        /// <param name="user">User to get token for</param>
        /// <param name="scopes">Scopes for api to call</param>
        /// <param name="tenant"></param>
        private async Task <AuthenticationResult> AcquireTokenSilentAsync(
            IConfidentialClientApplication application, ClaimsPrincipal user,
            IEnumerable <string> scopes, string tenant)
        {
            var account = await GetUserAccountAsync(application, user);

            if (account == null)
            {
                return(null);
            }
            if (!string.IsNullOrWhiteSpace(tenant))
            {
                // Acquire an access token as another authority
                var authority = application.Authority.Replace(
                    new Uri(application.Authority).PathAndQuery, $"/{tenant}/");
                return(await application
                       .AcquireTokenSilent(scopes, account)
                       .WithAuthority(authority)
                       .ExecuteAsync());
            }
            return(await application
                   .AcquireTokenSilent(scopes, account)
                   .ExecuteAsync());
        }
Ejemplo n.º 4
0
        public async Task <string> GetToken(string scope)
        {
            var scopes = scope.Split(" ");

            var _claimsPrincipal = UserHttpContext.HttpContext.User;

            var upn = GetUsername(_claimsPrincipal);

            var account = await GetAccountByUsername(upn);

            //var account = await client.GetAccountAsync(upn.Value);
            var result = await client.AcquireTokenSilent(scopes, account).ExecuteAsync().ConfigureAwait(false);

            return(result.AccessToken);
        }
        /// <summary>
        /// Gets an access token for a downstream API on behalf of the user whose account is passed as an argument.
        /// </summary>
        /// <param name="application"><see cref="IConfidentialClientApplication"/>.</param>
        /// <param name="account">User IAccount for which to acquire a token.
        /// See <see cref="Microsoft.Identity.Client.AccountId.Identifier"/>.</param>
        /// <param name="scopes">Scopes for the downstream API to call.</param>
        /// <param name="authority">Authority based on a specific tenant for which to acquire a token to access the scopes
        /// on behalf of the user.</param>
        /// <param name="userFlow">Azure AD B2C user flow.</param>
        /// <param name="tokenAcquisitionOptions">Options passed-in to create the token acquisition object which calls into MSAL .NET.</param>
        private async Task <AuthenticationResult> GetAuthenticationResultForWebAppWithAccountFromCacheAsync(
            IConfidentialClientApplication application,
            IAccount?account,
            IEnumerable <string> scopes,
            string?authority,
            string?userFlow = null,
            TokenAcquisitionOptions?tokenAcquisitionOptions = null)
        {
            if (scopes == null)
            {
                throw new ArgumentNullException(nameof(scopes));
            }

            var builder = application
                          .AcquireTokenSilent(scopes.Except(_scopesRequestedByMsal), account)
                          .WithSendX5C(_microsoftIdentityOptions.SendX5C);

            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);
                }
            }

            // Acquire an access token as a B2C authority
            if (_microsoftIdentityOptions.IsB2C)
            {
                string b2cAuthority = application.Authority.Replace(
                    new Uri(application.Authority).PathAndQuery,
                    $"/{ClaimConstants.Tfp}/{_microsoftIdentityOptions.Domain}/{userFlow ?? _microsoftIdentityOptions.DefaultUserFlow}");

                builder.WithB2CAuthority(b2cAuthority)
                .WithSendX5C(_microsoftIdentityOptions.SendX5C);
            }
            else
            {
                builder.WithAuthority(authority);
            }

            return(await builder.ExecuteAsync()
                   .ConfigureAwait(false));
        }
Ejemplo n.º 6
0
        public async Task <AuthenticationResult> GetAccessTokenAsync(ClaimsPrincipal principal, string[] scopes)
        {
            IConfidentialClientApplication app = BuildApp(principal);
            IAccount account = await app.GetAccountAsync(principal.GetMsalAccountId());

            // guest??
            if (null == account)
            {
                System.Collections.Generic.IEnumerable <IAccount> accounts = await app.GetAccountsAsync();

                account = accounts.FirstOrDefault(a => a.Username == principal.GetLoginHint());
            }

            AuthenticationResult token = await app.AcquireTokenSilent(scopes, account).ExecuteAsync().ConfigureAwait(false);

            return(token);
        }
        public async Task <ActionResult> AccessToken()
        {
            // Before we render the send email screen, we use the incremental consent to obtain and cache the access token with the correct scopes
            IConfidentialClientApplication app    = MsalAppBuilder.BuildConfidentialClientApplication();
            AuthenticationResult           result = null;
            var accounts = await app.GetAccountsAsync();

            string[] scopes = { String.Format(" {0}/openid", AuthenticationConfig.Resource) };

            try
            {
                // try to get an already cached token
                result = await app.AcquireTokenSilent(scopes, accounts.FirstOrDefault()).ExecuteAsync().ConfigureAwait(false);

                ViewBag.AccessToken = result.AccessToken;
                ViewBag.Environment = result.Account.Environment;

                // The 'preferred_username' claim can be used for showing the user's primary way of identifying themselves
                ViewBag.Username = result.Account.Username;
            }
            catch (MsalUiRequiredException ex)
            {
                // A MsalUiRequiredException happened on AcquireTokenSilentAsync.
                // This indicates you need to call AcquireTokenAsync to acquire a token
                Debug.WriteLine($"MsalUiRequiredException: {ex.Message}");

                try
                {
                    // Build the auth code request Uri
                    string authReqUrl = await OAuth2RequestManager.GenerateAuthorizationRequestUrl(scopes, app, this.HttpContext, Url);

                    ViewBag.AuthorizationRequest = authReqUrl;
                    ViewBag.Relogin = "******";
                }
                catch (MsalException msalex)
                {
                    Response.Write($"Error Acquiring Token:{System.Environment.NewLine}{msalex}");
                }
            }
            catch (Exception ex)
            {
                Response.Write($"Error Acquiring Token Silently:{System.Environment.NewLine}{ex}");
            }

            return(View());
        }
Ejemplo n.º 8
0
        public async Task <ActionResult> Index()
        {
            IConfidentialClientApplication app    = MsalAppBuilder.BuildConfidentialClientApplication();
            AuthenticationResult           result = null;

            var accounts = await app.GetAccountsAsync();

            string[] scopes = { ProductApiConfiguration.ViewScope };

            try
            {
                // try to get token silently from the token cache
                result = await app.AcquireTokenSilent(scopes, accounts.FirstOrDefault()).ExecuteAsync().ConfigureAwait(false);
            }
            catch (MsalUiRequiredException)
            {
                ViewBag.Relogin = "******";
                return(View());
            }
            catch (Exception ex)
            {
                ViewBag.Error = "An error has occurred. Details: " + ex.Message;
                return(View());
            }
            var products = new List <Product>();

            if (result != null)
            {
                // Use the token to read email
                HttpClient httpClient = new HttpClient();
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", result.AccessToken);
                HttpResponseMessage responseMessage = await httpClient.GetAsync(ProductApiConfiguration.GetProductsUrl);

                string productsResult = await responseMessage.Content.ReadAsStringAsync();

                if (productsResult.Length > 0)
                {
                    products = JsonConvert.DeserializeObject <List <Product> >(productsResult);
                }
                ViewBag.Message = productsResult;
            }


            return(View(products));
        }
Ejemplo n.º 9
0
        public async Task <AuthenticationResult> AcquireTokenAsync(string tenantId, string audience)
        {
            InstantiateConfidentialClient(tenantId);

            var account = app_.GetAccountAsync(ClientId)
                          .ConfigureAwait(false)
                          .GetAwaiter()
                          .GetResult();
            var scopes = new List <string>()
            {
                audience
            };
            AuthenticationResult authResult = null;

            try
            {
                // go for the cache
                authResult = app_.AcquireTokenSilent(scopes, account)
                             .ExecuteAsync()
                             .ConfigureAwait(false)
                             .GetAwaiter()
                             .GetResult();

                return(authResult);
            }
            catch (MsalUiRequiredException ex)
            {
                Console.WriteLine($"silent token acquisition failed: {ex.GetType()}: {ex.ErrorCode}; falling back to interactive.");
            }

            try
            {
                authResult = await app_.AcquireTokenForClient(scopes)
                             .ExecuteAsync()
                             .ConfigureAwait(false);
            }
            catch (MsalClientException ex)
            {
                Console.WriteLine($"failed to acquire token for client: {ex.GetType()}: {ex.ErrorCode}; giving up.");
                throw;
            }

            return(authResult);
        }
Ejemplo n.º 10
0
        public static string GetToken(HttpContext httpContext)
        {
            string response;

            try
            {
                // Retrieve the token with the specified scopes
                string[] scope          = _options["Scopes"].Split(' ');
                string   signedInUserID = httpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value;

                IConfidentialClientApplication cca =
                    ConfidentialClientApplicationBuilder.Create(_options["ClientId"])
                    .WithClientSecret(_options["ClientSecret"])
                    .WithB2CAuthority("https://emsfiiot.b2clogin.com/tfp/emsfiiot.onmicrosoft.com/B2C_1_Signin/v2.0")
                    .Build();
                ITokenCache cache = new MSALStaticCache(signedInUserID, httpContext).EnablePersistence(cca.UserTokenCache);

                IEnumerable <IAccount> accounts     = cca.GetAccountsAsync().Result;
                AuthenticationResult   tokenRequest = cca.AcquireTokenSilent(scope, accounts.FirstOrDefault()).ExecuteAsync().Result;

                if (tokenRequest.AccessToken != null)
                {
                    httpContext.Response.Cookies.Append("ADB2CToken",
                                                        tokenRequest.AccessToken,
                                                        new CookieOptions
                    {
                        Expires = tokenRequest.ExpiresOn
                    });
                }

                response = tokenRequest.AccessToken;
            }
            catch (MsalUiRequiredException ex)
            {
                response = $"Session has expired. Please sign in again. {ex.Message}";
                httpContext.Response.Redirect("/Account/SignIn");
            }
            catch (Exception ex)
            {
                response = $"Error calling API: {ex.Message}";
            }

            return(response);
        }
Ejemplo n.º 11
0
        public async Task <string> GetAccessToken()
        {
            if (null == _userAccount)
            {
                return(null);
            }

            try
            {
                var result = await _msalClient
                             .AcquireTokenSilent(graphScopes, _userAccount)
                             .ExecuteAsync();

                return(result.AccessToken);
            }
            catch (System.Exception)
            {
                return(null);
            }
        }
        public async Task <ActionResult> SendMail()
        {
            // Before we render the send email screen, we use the incremental consent to obtain and cache the access token with the correct scopes
            IConfidentialClientApplication app = await MsalAppBuilder.BuildConfidentialClientApplication();

            AuthenticationResult result = null;
            var account = await app.GetAccountAsync(ClaimsPrincipal.Current.GetAccountId());

            string[] scopes = { "Mail.Send" };

            try
            {
                // try to get an already cached token
                result = await app.AcquireTokenSilent(scopes, account).ExecuteAsync().ConfigureAwait(false);
            }
            catch (MsalUiRequiredException ex)
            {
                // A MsalUiRequiredException happened on AcquireTokenSilentAsync.
                // This indicates you need to call AcquireTokenAsync to acquire a token
                Debug.WriteLine($"MsalUiRequiredException: {ex.Message}");

                try
                {
                    // Build the auth code request Uri
                    string authReqUrl = await OAuth2RequestManager.GenerateAuthorizationRequestUrl(scopes, app, this.HttpContext, Url);

                    ViewBag.AuthorizationRequest = authReqUrl;
                    ViewBag.Relogin = "******";
                }
                catch (MsalException msalex)
                {
                    Response.Write($"Error Acquiring Token:{System.Environment.NewLine}{msalex}");
                }
            }
            catch (Exception ex)
            {
                Response.Write($"Error Acquiring Token Silently:{System.Environment.NewLine}{ex}");
            }

            return(View());
        }
Ejemplo n.º 13
0
        private void button3_Click(object sender, EventArgs e)
        {
            try
            {
                //Refreshing token
                url = String.Format("https://login.microsoftonline.com/{0}/oauth2/v2.0/token", Domain.Text);

                var refreshT = app.AcquireTokenSilent(scopes, accnt).WithAuthority(url, true).ExecuteAsync();
                refreshT.Wait();
                string atr = refreshT.Result.AccessToken;
                refreshedToken.Text = atr;

                Logger.WriteLog("Access Token refreshed succesfully: " + "[" + tcount.ToString() + "] " + atr);
                tcount++;
            }
            catch
            {
                Logger.WriteLog("Issue with refreshing access token. Please try obtaining an access token again and then try refreshing.");
                throw;
            }
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Retrieve the token with the specified scopes
        /// </summary>
        /// <returns></returns>
        private async Task <AuthenticationResult> GetAuthenticationResultAsync()
        {
            var    scope          = AzureAdB2COptions.ApiScopes.Split(' ');
            string signedInUserID = HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value;

            IConfidentialClientApplication cca = ConfidentialClientApplicationBuilder.Create(AzureAdB2COptions.ClientId)
                                                 .WithRedirectUri(AzureAdB2COptions.RedirectUri)
                                                 .WithClientSecret(AzureAdB2COptions.ClientSecret)
                                                 .WithB2CAuthority(AzureAdB2COptions.Authority)
                                                 .Build();

            new MSALStaticCache(signedInUserID, this.HttpContext).EnablePersistence(cca.UserTokenCache);

            var accounts = await cca.GetAccountsAsync();

            AuthenticationResult result = accounts != null && accounts.Any()
                ? await cca.AcquireTokenSilent(scope, accounts.FirstOrDefault()).ExecuteAsync()
                : null;

            return(result);
        }
        public async Task <ActionResult> ReadMail()
        {
            IConfidentialClientApplication app = await MsalAppBuilder.BuildConfidentialClientApplication();

            AuthenticationResult result = null;
            var account = await app.GetAccountAsync(ClaimsPrincipal.Current.GetAccountId());

            string[] scopes = { "Mail.Read" };

            try
            {
                // try to get token silently
                result = await app.AcquireTokenSilent(scopes, account).ExecuteAsync().ConfigureAwait(false);
            }
            catch (MsalUiRequiredException)
            {
                ViewBag.Relogin = "******";
                return(View());
            }
            catch (Exception eee)
            {
                ViewBag.Error = "An error has occurred. Details: " + eee.Message;
                return(View());
            }

            if (result != null)
            {
                // Use the token to read email
                HttpClient hc = new HttpClient();
                hc.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", result.AccessToken);
                HttpResponseMessage hrm = await hc.GetAsync("https://graph.microsoft.com/v1.0/me/messages");

                string rez = await hrm.Content.ReadAsStringAsync();

                ViewBag.Message = rez;
            }

            return(View());
        }
        private async ValueTask <AccessToken> GetTokenImplAsync(bool async, TokenRequestContext requestContext, CancellationToken cancellationToken = default)
        {
            using CredentialDiagnosticScope scope = _pipeline.StartGetTokenScope($"{nameof(AuthorizationCodeCredential)}.{nameof(GetToken)}", requestContext);

            try
            {
                AccessToken token = default;

                if (_record is null)
                {
                    AuthenticationResult result = await _confidentialClient.AcquireTokenByAuthorizationCode(requestContext.Scopes, _authCode).ExecuteAsync(async, cancellationToken).ConfigureAwait(false);

                    _record = new AuthenticationRecord(result);

                    token = new AccessToken(result.AccessToken, result.ExpiresOn);
                }
                else
                {
                    AuthenticationResult result = await _confidentialClient.AcquireTokenSilent(requestContext.Scopes, (AuthenticationAccount)_record).ExecuteAsync(async, cancellationToken).ConfigureAwait(false);

                    token = new AccessToken(result.AccessToken, result.ExpiresOn);
                }

                return(scope.Succeeded(token));
            }
            catch (OperationCanceledException e)
            {
                scope.Failed(e);

                throw;
            }
            catch (Exception e)
            {
                throw scope.FailAndWrap(e);
            }
        }
Ejemplo n.º 17
0
        /// <summary>
        /// For web app, gets an access token for a downstream API on behalf of the signed-in user..
        /// </summary>
        /// <param name="requestedScopes"></param>
        /// <returns></returns>
        public async Task <AuthenticationResult> GetAccessTokenForUserAsync(IEnumerable <string> requestedScopes)
        {
            AuthenticationResult result = null;

            this.PrepareConfidentialClientInstanceAsync();

            try
            {
                IAccount account = await _application.GetAccountAsync(ClaimsPrincipal.Current.GetMsalAccountId());

                result = await _application.AcquireTokenSilent(requestedScopes, account)
                         .ExecuteAsync();

                return(result);
            }
            catch (MsalUiRequiredException ex)
            {
                // 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 ...
                //throw new MicrosoftIdentityWebChallengeUserException(ex, requestedScopes.ToArray(), null);

                throw ex;
            }
        }
Ejemplo n.º 18
0
        public async Task <string> CallAPI(string APIUrl, bool ispost = false)
        {
            string responseString = "";

            try
            {
                // Retrieve the token with the specified scopes
                var    scope          = AzureAdB2COptions.ApiScopes.Split(' ');
                string signedInUserID = HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value;

                IConfidentialClientApplication cca =
                    ConfidentialClientApplicationBuilder.Create(AzureAdB2COptions.ClientId)
                    .WithRedirectUri(AzureAdB2COptions.RedirectUri)
                    .WithClientSecret(AzureAdB2COptions.ClientSecret)
                    .WithB2CAuthority(AzureAdB2COptions.Authority)
                    .Build();
                new MSALStaticCache(signedInUserID, this.HttpContext).EnablePersistence(cca.UserTokenCache);

                var accounts = await cca.GetAccountsAsync();

                AuthenticationResult result = await cca.AcquireTokenSilent(scope, accounts.FirstOrDefault())
                                              .ExecuteAsync();

                HttpClient         client  = new HttpClient();
                HttpRequestMessage request = new HttpRequestMessage();
                if (ispost)
                {
                    request = new HttpRequestMessage(HttpMethod.Post, APIUrl);
                }
                else
                {
                    request = new HttpRequestMessage(HttpMethod.Get, APIUrl);
                }


                // Add token to the Authorization header and make the request
                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
                HttpResponseMessage response = await client.SendAsync(request);

                // Handle the response
                switch (response.StatusCode)
                {
                case HttpStatusCode.OK:
                    responseString = await response.Content.ReadAsStringAsync();

                    break;

                case HttpStatusCode.Unauthorized:
                    responseString = $"Please sign in again. {response.ReasonPhrase}";
                    break;

                default:
                    responseString = $"Error calling API. StatusCode=${response.StatusCode}";
                    break;
                }
            }
            catch (MsalUiRequiredException ex)
            {
                responseString = $"Session has expired. Please sign in again. {ex.Message}";
            }
            catch (Exception ex)
            {
                responseString = $"Error calling API: {ex.Message}";
            }
            return(responseString);
        }
        /// <summary>
        /// Returns an access token for a given site.
        /// </summary>
        /// <param name="siteUrl"></param>
        /// <returns></returns>
        public async Task <string> GetAccessTokenAsync(string siteUrl)
        {
            var uri = new Uri(siteUrl);

            AuthenticationResult authResult = null;

            var scopes = new[] { $"{uri.Scheme}://{uri.Authority}/.default" };

            switch (authenticationType)
            {
            case ClientContextType.AzureADCredentials:
            {
                var accounts = await publicClientApplication.GetAccountsAsync();

                try
                {
                    authResult = await publicClientApplication.AcquireTokenSilent(scopes, accounts.First()).ExecuteAsync();
                }
                catch
                {
                    authResult = await publicClientApplication.AcquireTokenByUsernamePassword(scopes, username, password).ExecuteAsync();
                }
                break;
            }

            case ClientContextType.AzureADInteractive:
            {
                var accounts = await publicClientApplication.GetAccountsAsync();

                try
                {
                    authResult = await publicClientApplication.AcquireTokenSilent(scopes, accounts.First()).ExecuteAsync();
                }
                catch
                {
                    authResult = await publicClientApplication.AcquireTokenInteractive(scopes).ExecuteAsync();
                }
                break;
            }

            case ClientContextType.AzureADCertificate:
            {
                var accounts = await confidentialClientApplication.GetAccountsAsync();

                try
                {
                    authResult = await confidentialClientApplication.AcquireTokenSilent(scopes, accounts.First()).ExecuteAsync();
                }
                catch
                {
                    authResult = await confidentialClientApplication.AcquireTokenForClient(scopes).ExecuteAsync();
                }
                break;
            }
            }
            if (authResult?.AccessToken != null)
            {
                return(authResult.AccessToken);
            }
            return(null);
        }
Ejemplo n.º 20
0
        public async Task <ActionResult> CallAPIPost()
        {
            ViewBag.Calc1Input1 = string.Empty;
            ViewBag.Calc1Input2 = string.Empty;
            ViewBag.Calc1Result = string.Empty;
            ViewBag.Calc2Input1 = string.Empty;
            ViewBag.Calc2Input2 = string.Empty;
            ViewBag.Calc2Result = string.Empty;

            if (!string.IsNullOrEmpty(Request.Form["btnFirstCalculation"]))
            {
                string signedInUserID = User.FindFirst(ClaimTypes.NameIdentifier).Value;
                string authority      = $"{_configuration.GetValue<string>("AzureADB2C:Instance")}/tfp/{_configuration.GetValue<string>("AzureADB2C:Domain")}/{_configuration.GetValue<string>("AzureADB2C:SignUpSignInPolicyId")}";

                // Build the redirect Uri from the current HttpContext
                // Ex. https://localhost:44340/signin-oidc
                string redirectUri = UriHelper.BuildAbsolute(this.Request.Scheme, this.Request.Host, this.Request.PathBase, this.Request.Path);

                // Create an instance of the ConfidentialClientApplication to retrieve the access token
                // via the authorization code using the authority, redirectUri, and the
                // client ID and client secret of the web application (from configuration)
                IConfidentialClientApplication cca = ConfidentialClientApplicationBuilder.Create(_configuration.GetValue <string>("AzureADB2C:ClientId"))
                                                     .WithB2CAuthority(authority)
                                                     .WithRedirectUri(redirectUri)
                                                     .WithClientSecret(_configuration.GetValue <string>("AzureADB2C:ClientSecret"))
                                                     .Build();

                // Construct a session-backed token cache based on the signed in User ID and the current HttpContext and attach it to the UserTokenCache of the ConfidentialClientApplication
                ITokenCache userTokenCache = new MSALSessionCache(signedInUserID, this.HttpContext, cca.UserTokenCache).GetMsalCacheInstance();

                // Retrieve the list of signed in accounts from the cache
                List <IAccount> accounts = (List <IAccount>) await cca.GetAccountsAsync();

                if (accounts.Count > 0)
                {
                    // Retrieve the access token for the API from the cache
                    AuthenticationResult authenticationResult = await cca.AcquireTokenSilent(_configuration.GetValue <string>("AzureADB2C:ApiScopes").Split(' '), accounts[0]).ExecuteAsync();

                    InputModel model = new InputModel();
                    if (Request.Form["calc1Input1"].ToString().IndexOf(".") > 0 ||
                        Request.Form["calc1Input2"].ToString().IndexOf(".") > 0)
                    {
                        model.DecimalInput = new decimal[] { Convert.ToDecimal(Request.Form["calc1Input1"]), Convert.ToDecimal(Request.Form["calc1Input2"]) };
                        model.StringInput  = new string[] { "Add", "Decimal" };
                    }
                    else
                    {
                        model.IntegerInput = new int[] { Convert.ToInt32(Request.Form["calc1Input1"]), Convert.ToInt32(Request.Form["calc1Input2"]) };
                        model.StringInput  = new string[] { "Add", "Integer" };
                    }
                    HttpClient httpClient = new HttpClient();
                    using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, _configuration.GetValue <string>("AzureADB2C:ApiUrl")))
                    {
                        // Set the authorization header
                        request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authenticationResult.AccessToken);
                        string content = JsonConvert.SerializeObject(model);
                        request.Content = new StringContent(content, Encoding.UTF8, "application/json");

                        // Send the request to Graph API endpoint
                        using (HttpResponseMessage response = await httpClient.SendAsync(request))
                        {
                            string error = await response.Content.ReadAsStringAsync();

                            // Check the result for error
                            if (!response.IsSuccessStatusCode)
                            {
                                // Throw server busy error message
                                if (response.StatusCode == (HttpStatusCode)429)
                                {
                                    // TBD: Add you error handling here
                                }

                                throw new Exception(error);
                            }

                            // Return the response body, usually in JSON format
                            OutputModel outputModel = JsonConvert.DeserializeObject <OutputModel>(await response.Content.ReadAsStringAsync());
                            if (model.StringInput[1] == "Integer")
                            {
                                ViewBag.Calc1Input1 = model.IntegerInput[0];
                                ViewBag.Calc1Input2 = model.IntegerInput[1];
                                ViewBag.Calc1Result = outputModel.IntegerOutput[0];
                            }
                            else
                            {
                                ViewBag.Calc1Input1 = model.DecimalInput[0];
                                ViewBag.Calc1Input2 = model.DecimalInput[1];
                                ViewBag.Calc1Result = outputModel.DecimalOutput[0];
                            }
                        }
                    }
                }
            }

            return(View());
        }
Ejemplo n.º 21
0
        public async Task <ActionResult> Create(string description)
        {
            try
            {
                ///
                /// Number validation occurs here, should be moved to external class
                ///
                if (System.Text.RegularExpressions.Regex.IsMatch(description, @"^[a-zA-Z]+$"))
                {
                    throw new WebException("Please provide a number");
                }
                if (String.IsNullOrEmpty(description))
                {
                    throw new WebException("Please provide a number");
                }
                if (description.Contains('.') && description.Split('.')[1].Length > 4)
                {
                    throw new WebException("The number can only have a precision of up to 4 decimal places");
                }
                if (description.Length >= 11)
                {
                    throw new WebException("number contains too many digits");
                }


                string accessToken = null;
                var    scope       = new string[] { Globals.WriteTasksScope };

                IConfidentialClientApplication cca = MsalAppBuilder.BuildConfidentialClientApplication();
                var accounts = await cca.GetAccountsAsync();

                AuthenticationResult result = await cca.AcquireTokenSilent(scope, accounts.FirstOrDefault()).ExecuteAsync();

                accessToken = result.AccessToken;

                // Set the content
                var httpContent = new[] { new KeyValuePair <string, string>("InputNumber", description) };

                // Create the request
                HttpClient         client  = new HttpClient();
                HttpContent        content = new FormUrlEncodedContent(httpContent);
                HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, apiEndpoint);
                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
                request.Content = content;
                HttpResponseMessage response = await client.SendAsync(request);

                // Handle the response
                switch (response.StatusCode)
                {
                case HttpStatusCode.OK:
                case HttpStatusCode.NoContent:
                case HttpStatusCode.Created:
                    return(new RedirectResult("/Numbers"));

                case HttpStatusCode.Unauthorized:
                    return(ErrorAction("Please sign in again. " + response.ReasonPhrase));

                default:
                    return(ErrorAction("Error. Status code = " + response.StatusCode));
                }
            }
            catch (MsalUiRequiredException ex)
            {
                /*
                 *  If the tokens have expired or become invalid for any reason, ask the user to sign in again.
                 *  Another cause of this exception is when you restart the app using InMemory cache.
                 *  It will get wiped out while the user will be authenticated still because of their cookies, requiring the TokenCache to be initialized again
                 *  through the sign in flow.
                 */
                return(new RedirectResult("/Account/SignUpSignIn?redirectUrl=/Numbers"));
            }
            catch (Exception ex)
            {
                return(ErrorAction("Error writing to list: " + ex.Message));
            }
        }
        private static async Task RunAsync()
        {
            var scopes = new string[] { "User.Read" };

            // Return the MsalAccountActivities of the users that you would like to acquire a token silently
            var someTimeAgo            = DateTime.Now.AddSeconds(-30);
            var accountsToAcquireToken = await _msalAccountActivityStore.GetMsalAccountActivitesSince(someTimeAgo);

            // Or you could also return the account activity of a particular user
            //var userActivityAccount = await _msalAccountActivityStore.GetMsalAccountActivityForUser("User-UPN");

            if (accountsToAcquireToken == null || accountsToAcquireToken.Count() == 0)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine($"No accounts returned");
                Console.ResetColor();
            }
            else
            {
                Console.WriteLine($"Trying to acquire token silently for {accountsToAcquireToken.Count()} activities...");
                Console.Write(Environment.NewLine);

                IConfidentialClientApplication app = await GetConfidentialClientApplication(config);

                // For each user's record, hydrate an IAccount with the values saved on the table, and call AcquireTokenSilent for this account.
                foreach (var account in accountsToAcquireToken)
                {
                    var hydratedAccount = new MsalAccount
                    {
                        HomeAccountId = new AccountId(
                            account.AccountIdentifier,
                            account.AccountObjectId,
                            account.AccountTenantId)
                    };

                    try
                    {
                        var result = await app.AcquireTokenSilent(scopes, hydratedAccount)
                                     .ExecuteAsync()
                                     .ConfigureAwait(false);

                        Console.WriteLine($"Token acquired for account: {account.UserPrincipalName}");
                        Console.WriteLine($"Access token preview: {result.AccessToken.Substring(0, 70)} ...");
                        Console.WriteLine("  <------------------------>  ");
                        Console.Write(Environment.NewLine);
                    }
                    catch (MsalUiRequiredException ex)
                    {
                        /*
                         * If MsalUiRequiredException is thrown for an account, it means that a user interaction is required
                         * thus the background worker wont be able to acquire a token silently for it.
                         * The user of that account will have to access the web app to perform this interaction.
                         * Examples that could cause this: MFA requirement, token expired or revoked, token cache deleted, etc
                         */
                        await _msalAccountActivityStore.HandleIntegratedTokenAcquisitionFailure(account);

                        Console.ForegroundColor = ConsoleColor.Red;
                        Console.WriteLine($"Could not acquire token for account {account.UserPrincipalName}.");
                        Console.WriteLine($"Error: {ex.Message}");
                        Console.WriteLine("  <------------------------>  ");
                        Console.Write(Environment.NewLine);
                        Console.ResetColor();
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                }
            }

            Console.ForegroundColor = ConsoleColor.Green;
            Console.Write(Environment.NewLine);
            Console.WriteLine($"Task completed.");
            Console.ResetColor();
        }
Ejemplo n.º 23
0
        public async Task <ActionResult> SendMail(string recipient, string subject, string body)
        {
            string messagetemplate = @"{{
  ""Message"": {{
    ""Subject"": ""{0}"",
    ""Body"": {{
                ""ContentType"": ""Text"",
      ""Content"": ""{1}""
    }},
    ""ToRecipients"": [
      {{
        ""EmailAddress"": {{
          ""Address"": ""{2}""
        }}
}}
    ],
    ""Attachments"": []
  }},
  ""SaveToSentItems"": ""false""
}}
";
            string message         = String.Format(messagetemplate, subject, body, recipient);

            HttpClient         client  = new HttpClient();
            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "https://graph.microsoft.com/v1.0/me/sendMail")
            {
                Content = new StringContent(message, Encoding.UTF8, "application/json")
            };


            IConfidentialClientApplication app    = MsalAppBuilder.BuildConfidentialClientApplication();
            AuthenticationResult           result = null;
            var account = await app.GetAccountAsync(ClaimsPrincipal.Current.GetMsalAccountId());

            string[] scopes = { "Mail.Send" };

            try
            {
                // try to get an already cached token
                result = await app.AcquireTokenSilent(scopes, account).ExecuteAsync().ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                /*
                 * When the user access this page (from the HTTP GET action result) we check if they have the scope "Mail.Send" and
                 * we handle the additional consent step in case it is needed. Then, we acquire an access token and MSAL cache it for us.
                 * So in this HTTP POST action result, we can always expect a token to be in cache. If they are not in the cache,
                 * it means that the user accessed this route via an unsual way.
                 */
                ViewBag.Error = "An error has occurred acquiring the token from cache. Details: " + ex.Message;
                return(View());
            }

            if (result != null)
            {
                // Use the token to send email

                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
                HttpResponseMessage response = await client.SendAsync(request);

                if (response.IsSuccessStatusCode)
                {
                    ViewBag.AuthorizationRequest = null;
                    return(View("MailSent"));
                }
            }


            return(View());
        }
        public async Task <IActionResult> Api()
        {
            string responseString;

            try
            {
                // Retrieve the token with the specified scopes
                var    scope          = AzureAdB2COptions.ApiScopes.Split(' ');
                string signedInUserID = HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value;

                IConfidentialClientApplication cca =
                    ConfidentialClientApplicationBuilder.Create(AzureAdB2COptions.ClientId)
                    .WithLogging(MyLoggingMethod, LogLevel.Verbose, enablePiiLogging: false, enableDefaultPlatformLogging: true)
                    .WithRedirectUri(AzureAdB2COptions.RedirectUri)
                    .WithClientSecret(AzureAdB2COptions.ClientSecret)
                    .WithB2CAuthority(AzureAdB2COptions.Authority)
                    .Build();
                new MSALStaticCache(signedInUserID, this.HttpContext).EnablePersistence(cca.UserTokenCache);

                var accounts = await cca.GetAccountsAsync();

                AuthenticationResult result = await cca.AcquireTokenSilent(scope, accounts.FirstOrDefault())
                                              .ExecuteAsync();

                if (result.AccessToken == null)
                {
                    ViewData["Title"]   = "JWT Token Problem";
                    ViewData["Payload"] = "The current user session does not have a valid access_token. Most likely the scopes do not match the App registration.";
                    return(View());
                }
                HttpClient         client  = new HttpClient();
                HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, AzureAdB2COptions.ApiUrl);

                // Add token to the Authorization header and make the request
                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
                HttpResponseMessage response = await client.SendAsync(request);

                // Handle the response
                switch (response.StatusCode)
                {
                case HttpStatusCode.OK:
                    responseString = await response.Content.ReadAsStringAsync();

                    break;

                case HttpStatusCode.Unauthorized:
                    responseString = $"Please sign in again. {response.ReasonPhrase}";
                    break;

                default:
                    responseString = $"Error calling API. StatusCode=${response.StatusCode}";
                    break;
                }
                client.Dispose();
            }
            catch (MsalUiRequiredException ex)
            {
                responseString = $"Session has expired. Please sign in again. {ex.Message}";
            }
            catch (Exception ex)
            {
                responseString = $"Error calling API: {ex.Message}";
            }

            ViewData["Payload"] = $"{responseString}";
            return(View());
        }