Exemplo n.º 1
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, 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(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;
                }
            }
            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());
        }
Exemplo n.º 2
0
        public async Task <IAccount> GetAccountByUsername(string username)
        {
            var accounts = await client.GetAccountsAsync();

            var account = accounts.Where(a => a.Username == username).FirstOrDefault();

            return(account);
        }
        public async Task <ActionResult> Create(string description)
        {
            try
            {
                // Retrieve the token with the specified scopes
                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>("Text", 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("/Tasks"));

                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=/Tasks"));
            }
            catch (Exception ex)
            {
                return(ErrorAction("Error writing to list: " + ex.Message));
            }
        }
Exemplo n.º 4
0
        /// <summary>
        ///     Gets an access token for a downstream API on behalf of the user which account ID is passed as an argument
        /// </summary>
        /// <param name="application"></param>
        /// <param name="accountIdentifier">
        ///     User account identifier 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="loginHint"></param>
        /// <param name="tenant"></param>
        private async Task <string> GetAccessTokenOnBehalfOfUserFromCacheAsync(
            IConfidentialClientApplication application,
            string accountIdentifier,
            IEnumerable <string> scopes,
            string loginHint,
            string tenant)
        {
            if (accountIdentifier == null)
            {
                throw new ArgumentNullException(nameof(accountIdentifier));
            }

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

            // Get the account
            var account = await application.GetAccountAsync(accountIdentifier).ConfigureAwait(false);

            // Special case for guest users as the Guest oid / tenant id are not surfaced.
            if (account == null)
            {
                if (loginHint == null)
                {
                    throw new ArgumentNullException(nameof(loginHint));
                }
                var accounts = await application.GetAccountsAsync().ConfigureAwait(false);

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

            AuthenticationResult result;

            if (string.IsNullOrWhiteSpace(tenant))
            {
                result = await application
                         .AcquireTokenSilent(scopes.Except(_scopesRequestedByMsalNet), account)
                         .ExecuteAsync()
                         .ConfigureAwait(false);
            }
            else
            {
                var authority =
                    application.Authority.Replace(new Uri(application.Authority).PathAndQuery, $"/{tenant}/");
                result = await application
                         .AcquireTokenSilent(scopes.Except(_scopesRequestedByMsalNet), account)
                         .WithAuthority(authority)
                         .ExecuteAsync()
                         .ConfigureAwait(false);
            }

            return(result.AccessToken);
        }
        /// <summary>
        /// Removes the account associated with context.HttpContext.User from the MSAL.NET cache.
        /// </summary>
        /// <param name="context">RedirectContext passed-in to a <see cref="OpenIdConnectEvents.OnRedirectToIdentityProviderForSignOut"/>
        /// Openidconnect event.</param>
        /// <returns></returns>
        public async Task RemoveAccountAsync(RedirectContext context)
        {
            ClaimsPrincipal user = context.HttpContext.User;
            IConfidentialClientApplication app = await GetOrBuildConfidentialClientApplicationAsync().ConfigureAwait(false);

            IAccount account = null;

            // For B2C, we should remove all accounts of the user regardless the user flow
            if (_microsoftIdentityOptions.IsB2C)
            {
                var b2cAccounts = await app.GetAccountsAsync().ConfigureAwait(false);

                foreach (var b2cAccount in b2cAccounts)
                {
                    await app.RemoveAsync(b2cAccount).ConfigureAwait(false);
                }

                _tokenCacheProvider?.ClearAsync().ConfigureAwait(false);
            }

            else
            {
                account = await app.GetAccountAsync(context.HttpContext.User.GetMsalAccountId()).ConfigureAwait(false);

                // Workaround for the guest account
                if (account == null)
                {
                    var accounts = await app.GetAccountsAsync().ConfigureAwait(false);

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

                if (account != null)
                {
                    await app.RemoveAsync(account).ConfigureAwait(false);

                    _tokenCacheProvider?.ClearAsync().ConfigureAwait(false);
                }
            }
        }
        /// <summary>
        /// Gets an access token for a downstream API on behalf of the user described by its claimsPrincipal.
        /// </summary>
        /// <param name="application"></param>
        /// <param name="claimsPrincipal">Claims principal for the user on behalf of whom to get a token.</param>
        /// <param name="scopes">Scopes for the downstream API to call.</param>
        /// <param name="tenant">(optional) Specific tenant for which to acquire a token to access the scopes
        /// on behalf of the user described in the claimsPrincipal.</param>
        private async Task <string> GetAccessTokenOnBehalfOfUserFromCacheAsync(
            IConfidentialClientApplication application,
            ClaimsPrincipal claimsPrincipal,
            IEnumerable <string> scopes,
            string tenant)
        {
            // Gets MsalAccountId for AAD and B2C scenarios
            string   accountIdentifier = claimsPrincipal.GetMsalAccountId();
            string   loginHint         = claimsPrincipal.GetLoginHint();
            IAccount account           = null;

            if (accountIdentifier != null)
            {
                account = await application.GetAccountAsync(accountIdentifier).ConfigureAwait(false);

                // Special case for guest users as the Guest oid / tenant id are not surfaced.
                // B2C should not follow this logic since loginHint is not present
                if (!_microsoftIdentityOptions.IsB2C && account == null)
                {
                    if (loginHint == null)
                    {
                        throw new ArgumentNullException(nameof(loginHint));
                    }

                    var accounts = await application.GetAccountsAsync().ConfigureAwait(false);

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

            // If it is B2C and could not get an account (most likely because there is no tid claims), try to get it by user flow
            if (_microsoftIdentityOptions.IsB2C && account == null)
            {
                string currentUserFlow = claimsPrincipal.GetUserFlowId();
                account = GetAccountByUserFlow(await application.GetAccountsAsync().ConfigureAwait(false), currentUserFlow);
            }

            return(await GetAccessTokenOnBehalfOfUserFromCacheAsync(application, account, scopes, tenant).ConfigureAwait(false));
        }
        // 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));
            }
        }
Exemplo n.º 8
0
        public async Task <bool> IsUserAuthenticated()
        {
            // If we already have the user account we're
            // authenticated
            if (null != _userAccount)
            {
                return(true);
            }

            // See if there are any accounts in the cache
            var accounts = await _msalClient.GetAccountsAsync();

            _userAccount = accounts.FirstOrDefault();
            return(null != _userAccount);
        }
        /// <summary>
        /// Removes the account associated with context.HttpContext.User from the MSAL.NET cache
        /// </summary>
        /// <param name="context">RedirectContext passed-in to a <see cref="OnRedirectToIdentityProviderForSignOut"/>
        /// Openidconnect event</param>
        /// <returns></returns>
        public async Task RemoveAccount(RedirectContext context)
        {
            ClaimsPrincipal user = context.HttpContext.User;
            IConfidentialClientApplication app = CreateApplication(context.HttpContext, user);
            IAccount account = await app.GetAccountAsync(context.HttpContext.User.GetMsalAccountId());

            // Workaround for the guest account
            if (account == null)
            {
                var accounts = await app.GetAccountsAsync();

                account = accounts.FirstOrDefault(a => a.Username == user.GetLoginHint());
            }
            await app.RemoveAsync(account);
        }
        public static async Task ClearUserTokenCache()
        {
            IConfidentialClientApplication clientapp = ConfidentialClientApplicationBuilder.Create(AuthenticationConfig.ClientId)
                                                       .WithClientSecret(AuthenticationConfig.ClientSecret)
                                                       .WithRedirectUri(AuthenticationConfig.RedirectUri)
                                                       .WithAuthority(new Uri(AuthenticationConfig.Authority))
                                                       .Build();

            // We only clear the user's tokens.
            MSALPerUserMemoryTokenCache userTokenCache = new MSALPerUserMemoryTokenCache(clientapp.UserTokenCache, ClaimsPrincipal.Current);
            var userAccounts = await clientapp.GetAccountsAsync();

            await clientapp.RemoveAsync(userAccounts.FirstOrDefault());

            userTokenCache.Clear();
        }
        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());
        }
Exemplo n.º 12
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);
        }
Exemplo n.º 13
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));
        }
Exemplo n.º 14
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);
        }
Exemplo n.º 15
0
        /// <summary>
        /// Common method to remove the cached tokens for the currently signed in user
        /// </summary>
        /// <returns></returns>
        public static async Task ClearUserTokenCache()
        {
            IConfidentialClientApplication clientapp = ConfidentialClientApplicationBuilder.Create(B2C_Globals.ClientId)
                                                       .WithB2CAuthority(B2C_Globals.Authority)
                                                       .WithClientSecret(B2C_Globals.ClientSecret)
                                                       .WithRedirectUri(B2C_Globals.RedirectUri)
                                                       .Build();

            // We only clear the user's tokens.
            MSALPerUserMemoryTokenCache userTokenCache = new MSALPerUserMemoryTokenCache(clientapp.UserTokenCache);
            var userAccounts = await clientapp.GetAccountsAsync();

            foreach (var account in userAccounts)
            {
                //Remove the users from the MSAL's internal cache
                await clientapp.RemoveAsync(account);
            }
            userTokenCache.Clear();
        }
Exemplo n.º 16
0
        /// <summary>
        /// Removes the account associated with context.HttpContext.User from the MSAL.NET cache
        /// </summary>
        /// <param name="context">RedirectContext passed-in to a Openidconnect event</param>
        /// <returns></returns>
        public async Task RemoveAccountAsync(RedirectContext context)
        {
            ClaimsPrincipal user = context.HttpContext.User;
            IConfidentialClientApplication app = BuildConfidentialClientApplication(context.HttpContext, user);
            IAccount account = await app.GetAccountAsync(context.HttpContext.User.GetMsalAccountId()).ConfigureAwait(false);

            // Workaround for the guest account
            if (account == null)
            {
                var accounts = await app.GetAccountsAsync().ConfigureAwait(false);

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

            // AppTokenCacheProvider?.Clear();
            _userTokenCacheProvider?.Clear();

            await app.RemoveAsync(account).ConfigureAwait(false);
        }
Exemplo n.º 17
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);
        }
Exemplo n.º 18
0
        public async Task <ActionResult> ReadMail()
        {
            IConfidentialClientApplication app    = MsalAppBuilder.BuildConfidentialClientApplication();
            AuthenticationResult           result = null;
            var accounts = await app.GetAccountsAsync();

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

            try
            {
                // try to get token silently
                result = await app.AcquireTokenSilent(scopes, accounts.FirstOrDefault()).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());
        }
        // GET: Admin
        public async Task <ActionResult> Index()
        {
            string[] scopes = adminScopes.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
            SessionTokenCacheProvider      sessionTokenCacheProvider = new SessionTokenCacheProvider(this.HttpContext);
            IConfidentialClientApplication cca = AuthorizationCodeProvider.CreateClientApplication(clientId, redirectUri, new ClientCredential(appKey), sessionTokenCacheProvider);

            try
            {
                AuthenticationResult result = await cca.AcquireTokenSilentAsync(scopes, (await cca.GetAccountsAsync()).FirstOrDefault());
            }
            catch (Exception)
            {
                try
                {// when failing, manufacture the URL and assign it
                    string authReqUrl = await OAuth2RequestManager.GenerateAuthorizationRequestUrl(scopes, cca as ConfidentialClientApplication, this.HttpContext, Url);

                    ViewBag.AuthorizationRequest = authReqUrl;
                }
                catch (Exception ee)
                {
                }
            }

            return(View("Admin"));
        }
Exemplo 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());
        }
Exemplo 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));
            }
        }
Exemplo n.º 22
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/microsoft.graph.sendMail")
            {
                Content = new StringContent(message, Encoding.UTF8, "application/json")
            };


            IConfidentialClientApplication app    = MsalAppBuilder.BuildConfidentialClientApplication();
            AuthenticationResult           result = null;
            var accounts = await app.GetAccountsAsync();

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

            try
            {
                // try to get an already cached token
                result = await app.AcquireTokenSilent(scopes, accounts.FirstOrDefault()).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());
        }
        /// <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);
        }