public async Task <ActionResult> SendMail()
        {
            // try to get token silently
            string     signedInUserID         = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
            TokenCache userTokenCache         = new MSALSessionCache(signedInUserID, this.HttpContext).GetMsalCacheInstance();
            ConfidentialClientApplication cca = new ConfidentialClientApplication(clientId, redirectUri, new ClientCredential(appKey), userTokenCache, null);
            var accounts = await cca.GetAccountsAsync();

            if (accounts.Any())
            {
                string[] scopes = { "Mail.Send" };
                try
                {
                    AuthenticationResult result = await cca.AcquireTokenSilentAsync(scopes, accounts.First());
                }
                catch (MsalUiRequiredException)
                {
                    try
                    {// when failing, manufacture the URL and assign it
                        string authReqUrl = await WebApp.Utils.OAuth2RequestManager.GenerateAuthorizationRequestUrl(scopes, cca, this.HttpContext, Url);

                        ViewBag.AuthorizationRequest = authReqUrl;
                    }
                    catch (Exception ee)
                    {
                        Response.Write(ee.Message);
                    }
                }
            }
            else
            {
            }
            return(View());
        }
        private async Task <string> GetAccessTokenAsync()
        {
            var        scope                  = _veracityIntegrationOptions.VeracityPlatformServiceScopes.Split(' ');
            TokenCache userTokenCache         = new MSALSessionCache(_httpContext).GetMsalCacheInstance();
            ConfidentialClientApplication cca = new ConfidentialClientApplication(_veracityIntegrationOptions.ClientId,
                                                                                  _veracityIntegrationOptions.Authority,
                                                                                  _veracityIntegrationOptions.RedirectUri,
                                                                                  new ClientCredential(_veracityIntegrationOptions.ClientSecret),
                                                                                  userTokenCache,
                                                                                  null);

            try
            {
                IEnumerable <IAccount> accounts = await cca.GetAccountsAsync();

                IAccount firstAccount = accounts.FirstOrDefault();
                var      result       = await cca.AcquireTokenSilentAsync(
                    scope,
                    firstAccount,
                    _veracityIntegrationOptions.Authority,
                    false);

                return(result.AccessToken);
            }
            catch (MsalUiRequiredException)
            {
                // Cannot find any cache user in memory, you should sign out and login again.
                throw new AuthenticationException("Cannot find login user credential, please sign out and login again");
            }
        }
예제 #3
0
        private static GraphServiceClient GetAuthenticatedClient()
        {
            return(new GraphServiceClient(
                       new DelegateAuthenticationProvider(
                           async(requestMessage) =>
            {
                // Get the signed in user's id and create a token cache
                string signedInUserId = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
                SessionTokenStore tokenStore = new SessionTokenStore(signedInUserId,
                                                                     new HttpContextWrapper(HttpContext.Current));

                var idClient = new ConfidentialClientApplication(
                    appId, redirectUri, new ClientCredential(appSecret),
                    tokenStore.GetMsalCacheInstance(), null);

                var accounts = await idClient.GetAccountsAsync();

                // By calling this here, the token can be refreshed
                // if it's expired right before the Graph call is made
                var result = await idClient.AcquireTokenSilentAsync(
                    graphScopes.Split(' '), accounts.FirstOrDefault());

                requestMessage.Headers.Authorization =
                    new AuthenticationHeaderValue("Bearer", result.AccessToken);
            })));
        }
예제 #4
0
        /*----------------------------------------------------------------------------
        *       %%Function: GetAccessToken
        *       %%Qualified: WebApp._default.GetAccessToken
        *
        *   Get an access token for accessing the WebApi. This will use
        *   AcquireTokenSilentAsync to get the token. Since this is using the
        *   same tokencache as we populated when the user logged in, we will
        *   get the access token from that cache.
        *  ----------------------------------------------------------------------------*/
        string GetAccessToken()
        {
            // Retrieve the token with the specified scopes
            var        scopes                 = new string[] { Startup.scopeWebApi };
            string     userId                 = GetUserId();
            TokenCache tokenCache             = new MSALSessionCache(userId, GetContextBase()).GetMsalCacheInstance();
            ConfidentialClientApplication cca = new ConfidentialClientApplication(Startup.clientId, Startup.authority,
                                                                                  Startup.redirectUri, new ClientCredential(Startup.appKey), tokenCache, null);

            Task <IEnumerable <IAccount> > tskAccounts = cca.GetAccountsAsync();

            tskAccounts.Wait();

            IAccount account = tskAccounts.Result.FirstOrDefault();

            if (account == null)
            {
                return(null);
            }

            Task <AuthenticationResult> tskResult =
                cca.AcquireTokenSilentAsync(scopes, account, Startup.authority, false);

            tskResult.Wait();
            return(tskResult.Result.AccessToken);
        }
        // this is how you get tokens obtained by the OIDC middleware
        //private Task<string> GetAccessTokenAsync()
        //{
        //    return httpContextAccessor.HttpContext.GetTokenAsync("access_token");
        //}

        // this is how you get tokens with MSAL
        private async Task <string> GetAccessTokenAsync()
        {
            try
            {
                var principal = httpContextAccessor.HttpContext.User;

                var tokenCache = new DistributedTokenCache(distributedCache, principal.FindFirst(Constants.ObjectIdClaimType).Value).GetMSALCache();
                var client     = new ConfidentialClientApplication(authOptions.ClientId,
                                                                   authOptions.GetAuthority(principal.FindFirst(Constants.AcrClaimType).Value),
                                                                   "https://app", // it's not really needed
                                                                   new ClientCredential(authOptions.ClientSecret),
                                                                   tokenCache,
                                                                   null);

                var account = (await client.GetAccountsAsync()).FirstOrDefault();

                var result = await client.AcquireTokenSilentAsync(new[] { $"{authOptions.ApiIdentifier}/read_values" },
                                                                  account);

                return(result.IdToken);
            }
            catch (MsalUiRequiredException)
            {
                throw new ReauthenticationRequiredException();
            }
        }
        private async Task <AuthenticationResult> GetToken()
        {
            var accounts = await _confidentialClientApplication.GetAccountsAsync();

            return(await _confidentialClientApplication.AcquireTokenSilentAsync(_azureAdB2COptions.Scopes,
                                                                                accounts.FirstOrDefault(), _azureAdB2COptions.Authority, false));
        }
예제 #7
0
        public async Task <string> GetUserAccessTokenAsync()
        {
            string                        signedInUserID = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
            HttpContextWrapper            httpContext    = new HttpContextWrapper(HttpContext.Current);
            TokenCache                    userTokenCache = new SessionTokenCache(signedInUserID, httpContext).GetMsalCacheInstance();
            ConfidentialClientApplication cca            = new ConfidentialClientApplication(appId, redirectUri, new ClientCredential(appSecret), userTokenCache, null);

            try
            {
                var accounts = await cca.GetAccountsAsync();

                AuthenticationResult result = await cca.AcquireTokenSilentAsync(scopes.Split(new char[] { ' ' }), accounts.First());

                return(result.AccessToken);
            }

            catch (Exception)
            {
                HttpContext.Current.Request.GetOwinContext().Authentication.Challenge(
                    new AuthenticationProperties()
                {
                    RedirectUri = "/"
                },
                    OpenIdConnectAuthenticationDefaults.AuthenticationType);

                throw new Exception();
            }
        }
예제 #8
0
        public async Task AuthorizationCodeRequestTestAsync()
        {
            await RunWithMockHttpAsync(
                async (httpManager, serviceBundle, receiver) =>
            {
                httpManager.AddInstanceDiscoveryMockHandler();

                var cache = new TokenCache()
                {
                    BeforeAccess = BeforeCacheAccess,
                    AfterAccess  = AfterCacheAccess
                };

                var cc  = new ClientCredential("secret");
                var app = new ConfidentialClientApplication(
                    serviceBundle,
                    MsalTestConstants.ClientId,
                    "https://" + MsalTestConstants.ProductionPrefNetworkEnvironment + "/tfp/home/policy",
                    MsalTestConstants.RedirectUri,
                    cc,
                    cache,
                    null)
                {
                    ValidateAuthority = false
                };

                httpManager.AddMockHandlerForTenantEndpointDiscovery(MsalTestConstants.AuthorityHomeTenant, "p=policy");
                httpManager.AddSuccessTokenResponseMockHandlerForPost();

                var result = await app.AcquireTokenByAuthorizationCodeAsync("some-code", MsalTestConstants.Scope)
                             .ConfigureAwait(false);
                Assert.IsNotNull(result);
                Assert.AreEqual(1, app.UserTokenCache.TokenCacheAccessor.AccessTokenCount);
                Assert.AreEqual(1, app.UserTokenCache.TokenCacheAccessor.RefreshTokenCount);

                cache = new TokenCache()
                {
                    BeforeAccess = BeforeCacheAccess,
                    AfterAccess  = AfterCacheAccess
                };

                app = new ConfidentialClientApplication(
                    MsalTestConstants.ClientId,
                    "https://" + MsalTestConstants.ProductionPrefNetworkEnvironment + "/tfp/home/policy",
                    MsalTestConstants.RedirectUri,
                    cc,
                    cache,
                    null)
                {
                    ValidateAuthority = false
                };

                IEnumerable <IAccount> users = await app.GetAccountsAsync().ConfigureAwait(false);
                Assert.AreEqual(1, users.Count());
            }).ConfigureAwait(false);
        }
        // Use MSAL to get a the token we need for the Microsoft Graph
        private async Task <string> GetGraphAccessToken(string userId, string[] scopes)
        {
            TokenCache userTokenCache        = new MsalSessionTokenCache(userId, HttpContext).GetMsalCacheInstance();
            ConfidentialClientApplication cc = new ConfidentialClientApplication(Globals.ClientId, Globals.RedirectUri, new ClientCredential(Globals.ClientSecret), userTokenCache, null);
            var accounts = await cc.GetAccountsAsync();

            AuthenticationResult result = await cc.AcquireTokenSilentAsync(scopes, accounts.First());

            return(result.AccessToken);
        }
예제 #10
0
        public async Task Used_For_ConfidentialClientApplication_Succeeds()
        {
// msal acquiretokenbyauthorizationcodeasync ->
// https://azure.microsoft.com/en-us/resources/samples/active-directory-dotnet-webapp-openidconnect-v2/
// https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/Acquiring-tokens-with-authorization-codes-on-web-apps
// app registrations | {confidential client} | api permissions | add a permission | see best practices for requesting permissions ->
// https://docs.microsoft.com/en-us/azure/active-directory/develop/v1-permissions-and-consent

            var app = new ConfidentialClientApplication(confidentialClientId, confidentialClientRedirectUri,
                                                        new ClientCredential(confidentialClientSecret), FileTokenCache.GetUserCache(/* cacheFilePath: "d://temp//my.msalcache.bin", */ cacheFileProtect: false), null);
            //new ClientCredential(confidentialClientSecret), RedisTokenCache.GetAppOrUserCache(uniqueId), null);
            var accounts = await app.GetAccountsAsync();

            AuthenticationResult authResult = null;

            //scopes = new string[] { msftGraphResource };
            //scopes = new string[] { "openid profile offline_access Mail.Read Mail.Send" };

            try
            {
                // attempt to acquire valid token from cache or if expired use refresh token to silently acquire and cache new one
                authResult = await app.AcquireTokenSilentAsync(scopes, accounts.FirstOrDefault());
            }
            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
                {
                    authResult = await app.AcquireTokenByAuthorizationCodeAsync(authorizationCode, scopes);

                    //authResult = await app.AcquireTokenOnBehalfOfAsync(scopes, new UserAssertion(accessToken));
                }
                catch (MsalException msalex)
                {
                    // ErrorCode: invalid_grant, StatusCode: 400 implies you need ???
                    // ErrorCode: invalid_scope  StatusCode: 400 implies you need ???
                    Debug.WriteLine($"Error Acquiring Token:{System.Environment.NewLine}{msalex}");
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"Error Acquiring Token Silently:{System.Environment.NewLine}{ex}");
            }

            //var jwt = GetJsonWebToken(authResult.AccessToken); var actual = jwt["body"]["oid"].Value<string>();
            //var jwt = new JwtSecurityTokenHandler().ReadJwtToken(authResult.AccessToken); var actual = jwt.Payload["oid"];
            var actual = authResult.UniqueId;

            var expected = uniqueId;

            Assert.True(actual == expected);
        }
        public async Task <ActionResult> DeleteSubscription()
        {
            string subscriptionsEndpoint = "https://graph.microsoft.com/v1.0/subscriptions/";
            string subscriptionId        = (string)Session["SubscriptionId"];

            // Build the request.
            HttpClient client = new HttpClient();

            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Delete, subscriptionsEndpoint + subscriptionId);

            // try to get token silently
            string     signedInUserID         = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
            TokenCache userTokenCache         = new MSALSessionCache(signedInUserID, this.HttpContext).GetMsalCacheInstance();
            ConfidentialClientApplication cca = new ConfidentialClientApplication(clientId, redirectUri, new ClientCredential(appKey), userTokenCache, null);
            var accounts = await cca.GetAccountsAsync();

            if (accounts.Any())
            {
                string[] scopes = { "Mail.Read" };
                try
                {
                    AuthenticationResult result = await cca.AcquireTokenSilentAsync(scopes, accounts.First());

                    request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);

                    // Send the `DELETE subscriptions/id` request.
                    HttpResponseMessage response = await client.SendAsync(request);

                    if (!response.IsSuccessStatusCode)
                    {
                        return(RedirectToAction("Index", "Error", new { message = response.StatusCode, debug = response.Content.ReadAsStringAsync() }));
                    }
                }
                catch (MsalUiRequiredException)
                {
                    try
                    {// when failing, manufacture the URL and assign it
                        string authReqUrl = await WebApp.Utils.OAuth2RequestManager.GenerateAuthorizationRequestUrl(scopes, cca, this.HttpContext, Url);

                        ViewBag.AuthorizationRequest = authReqUrl;
                    }
                    catch (Exception ee)
                    {
                        Response.Write(ee.Message);
                    }
                }
            }
            else
            {
            }
            return(RedirectToAction("SignOut", "Account"));
        }
예제 #12
0
        /// <summary>
        /// GetAuthenticationDetailAsync
        /// </summary>
        /// <returns></returns>
        public async Task <OAuth2AccessResponse> GetAuthenticationDetailAsync()
        {
            var mailResponse = new OAuth2AccessResponse();
            var token        = string.Empty;

            try
            {
                token = _clientConfig.MailDataStore.Get($"{_clientConfig.MailDataStore.StoreKey}_MSMailToken") as string;

                if (string.IsNullOrEmpty(token))
                {
                    mailResponse.ErrorMessage = "Access Token has expired.";
                }


                if (string.IsNullOrWhiteSpace(token))
                {
                    var msalCache   = new TokenCacheModel.MicrosoftTokenStore(_clientConfig.MailDataStore, DateTimeOffset.Now.AddDays(90));
                    var msalSession = msalCache.GetMsalCacheInstance();
                    var cca         = new ConfidentialClientApplication(_clientConfig.OAuth2TokenizeRequestInfo.ClientId, _clientConfig.OAuth2TokenizeRequestInfo.RedirectUrl, new ClientCredential(_clientConfig.OAuth2TokenizeRequestInfo.ClientSecret), msalSession, null);

                    var accounts = await cca.GetAccountsAsync();

                    if (accounts != null && accounts.Any())
                    {
                        var graphScopes = _clientConfig.OAuth2TokenizeRequestInfo.Scope.Split(' ');
                        var result      = await cca.AcquireTokenSilentAsync(graphScopes, accounts.First(), null, true).ConfigureAwait(false);;

                        if (result != null)
                        {
                            _clientConfig.MailDataStore.Add($"{_clientConfig.MailDataStore.StoreKey}_MSMailToken", result.AccessToken, result.ExpiresOn);

                            token = result.AccessToken;
                        }
                    }

                    if (string.IsNullOrWhiteSpace(token))
                    {
                        mailResponse.ErrorMessage += " Re-authenticate.";
                    }
                }
            }
            catch (Exception ex)
            {
                mailResponse.ErrorMessage += ex.Message;
            }

            mailResponse.IsSucces = !string.IsNullOrWhiteSpace(token);
            mailResponse.Token    = token;
            _token = token;
            return(mailResponse);
        }
예제 #13
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;
                TokenCache userTokenCache         = new MSALSessionCache(signedInUserID, this.HttpContext).GetMsalCacheInstance();
                ConfidentialClientApplication cca = new ConfidentialClientApplication(AzureAdB2COptions.ClientId, AzureAdB2COptions.Authority, AzureAdB2COptions.RedirectUri, new ClientCredential(AzureAdB2COptions.ClientSecret), userTokenCache, null);

                var accounts = await cca.GetAccountsAsync();

                AuthenticationResult result = await cca.AcquireTokenSilentAsync(scope, accounts.FirstOrDefault(), AzureAdB2COptions.Authority, false);

                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());
        }
예제 #14
0
        /// <summary>
        /// Gets an access token and its expiration date. First tries to get the token from the token cache.
        /// </summary>
        /// <param name="userId">optional parameter to get the access token using a user Id</param>
        /// <returns></returns>
        public async Task <string> GetUserAccessTokenAsync(string userId)
        {
            // user Id will be passed when trying to authenticate a notification
            var currentUserId = !string.IsNullOrEmpty(userId) ? userId : ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;

            HttpContextBase context = HttpContext.Current.GetOwinContext().Environment["System.Web.HttpContextBase"] as HttpContextBase;

            TokenCache = new SessionTokenCache(
                currentUserId).GetMsalCacheInstance();

            if (!_redirectUri.EndsWith("/"))
            {
                _redirectUri = _redirectUri + "/";
            }
            string[] segments = context?.Request.Path.Split('/');
            ConfidentialClientApplication cca = new ConfidentialClientApplication(_appId, _redirectUri + segments?[1], new ClientCredential(_appSecret), TokenCache, null);
            bool?isAdmin = HttpContext.Current.Session["IsAdmin"] as bool?;

            string allScopes = _nonAdminScopes;

            if (isAdmin.GetValueOrDefault())
            {
                allScopes += " " + _adminScopes;
            }

            string[] scopes = allScopes.Split(' ');
            try
            {
                var accounts = await cca.GetAccountsAsync();

                AuthenticationResult result = await cca.AcquireTokenSilentAsync(scopes, accounts.First());

                return(result.AccessToken);
            }

            // Unable to retrieve the access token silently.
            catch (Exception)
            {
                HttpContext.Current.Request.GetOwinContext().Authentication.Challenge(
                    new AuthenticationProperties {
                    RedirectUri = _redirectUri + segments?[1]
                },
                    OpenIdConnectAuthenticationDefaults.AuthenticationType);

                throw new ServiceException(
                          new Error
                {
                    Code    = GraphErrorCode.AuthenticationFailure.ToString(),
                    Message = "Caller needs to authenticate.",
                });
            }
        }
        /// <summary>
        /// Gets an access token. First tries to get the access token from the token cache using password (secret) to authenticate. Production apps should use a certificate.
        /// </summary>
        public async Task <string> GetUserAccessTokenAsync(string userId)
        {
            var cca = new ConfidentialClientApplication(
                AzureAdOptions.Settings.ClientId,
                AzureAdOptions.Settings.BaseUrl + AzureAdOptions.Settings.CallbackPath,
                new ClientCredential(AzureAdOptions.Settings.ClientSecret),
                new SessionTokenCache(userId, _memoryCache).GetCacheInstance(),
                null);

            IAccount[] accounts = (await cca.GetAccountsAsync()).ToArray();

            return(accounts.Any() ? (await cca.AcquireTokenSilentAsync(AzureAdOptions.Settings.Scopes.Split(new[] { ' ' }), accounts.First())).AccessToken : null);
        }
        public async Task <ActionResult> Used()
        {
            var ret = new UsedInsights();

            HttpClient         client  = new HttpClient();
            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "https://graph.microsoft.com/beta/me/insights/used");

            // try to get token silently
            string     signedInUserID         = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
            TokenCache userTokenCache         = new MSALSessionCache(signedInUserID, this.HttpContext).GetMsalCacheInstance();
            ConfidentialClientApplication cca = new ConfidentialClientApplication(clientId, redirectUri, new ClientCredential(appKey), userTokenCache, null);
            var accounts = await cca.GetAccountsAsync();

            if (accounts.Any())
            {
                string[] scopes = { "Sites.Read.All" };
                try
                {
                    AuthenticationResult result = await cca.AcquireTokenSilentAsync(scopes, accounts.First());

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

                    if (response.IsSuccessStatusCode)
                    {
                        var responseBody = await response.Content.ReadAsStringAsync();

                        ret = JsonConvert.DeserializeObject <UsedInsights>(responseBody);

                        ViewBag.AuthorizationRequest = null;
                    }
                }
                catch (MsalUiRequiredException)
                {
                    try
                    {// when failing, manufacture the URL and assign it
                        string authReqUrl = await WebApp.Utils.OAuth2RequestManager.GenerateAuthorizationRequestUrl(scopes, cca, this.HttpContext, Url);

                        ViewBag.AuthorizationRequest = authReqUrl;
                    }
                    catch (Exception ee)
                    {
                        Response.Write(ee.Message);
                    }
                }
            }
            else
            {
            }
            return(View(ret));
        }
예제 #17
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="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>
        private async Task <string> GetAccessTokenOnBehalfOfUser(HttpContext httpContext, ConfidentialClientApplication application, string accountIdentifier, IEnumerable <string> scopes)
        {
            if (accountIdentifier == null)
            {
                throw new ArgumentNullException(nameof(accountIdentifier));
            }

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

            var accounts = await application.GetAccountsAsync();

            try
            {
                AuthenticationResult result = null;
                var allAccounts             = await application.GetAccountsAsync();

                IAccount account = await application.GetAccountAsync(accountIdentifier);

                result = await application.AcquireTokenSilentAsync(scopes.Except(_scopesRequestedByMsalNet), account);

                return(result.AccessToken);
            }
            catch (MsalUiRequiredException ex)
            {
                ReplyForbiddenWithWwwAuthenticateHeader(httpContext, scopes, ex);
                return(null);
            }
            catch (MsalException ex)
            {
                // TODO process the exception see if this is retryable etc ...
                throw;
            }
        }
예제 #18
0
        private async Task <AuthenticationResult> GetAuthResultAsync()
        {
            // Retrieve the token with the specified scopes
            string     signedInUserID         = HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value;
            TokenCache userTokenCache         = new MSALSessionCache(signedInUserID, this.HttpContext).GetMsalCacheInstance();
            ConfidentialClientApplication cca = new ConfidentialClientApplication(clientId, authority, redirectUri, new ClientCredential(clientSecret), userTokenCache, null);

            //var user = cca.Users.FirstOrDefault();
            var user = cca.GetAccountsAsync().Result.FirstOrDefault();

            if (user == null)
            {
                throw new Exception("The User is NULL.  Please clear your cookies and try again.");
            }

            return(await cca.AcquireTokenSilentAsync(scope, user, authority, false));
        }
        public static GraphServiceClient GetAuthenticatedClient(string userId, string redirect)
        {
            var graphClient = new GraphServiceClient(
                new DelegateAuthenticationProvider(
                    async(request) =>
            {
                var tokenCache = new SampleTokenCache(userId);

                var cca = new ConfidentialClientApplication(Startup.ClientId, redirect,
                                                            new ClientCredential(Startup.ClientSecret), tokenCache.GetMsalCacheInstance(), null);

                var accounts   = await cca.GetAccountsAsync();
                var authResult = await cca.AcquireTokenSilentAsync(Startup.Scopes, accounts.First());
                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
            }));

            return(graphClient);
        }
예제 #20
0
        /// <summary>
        /// Retrieves the cached access token for the WebAPI. If an access token cannot be found in the
        /// cache, return an empty access token.
        /// </summary>
        /// <returns>WebAPI access token. Empty if a cached access token cannot be found.</returns>
        private async Task <string> GetAPIAccessToken()
        {
            string accessToken = string.Empty;

            // The cache is built using the signed in user's identity so we must retrieve their name identifier
            // from the claims collection
            string signedInUserID = User.FindFirst(ClaimTypes.NameIdentifier).Value;

            // Build the identifier for the token issuing authority. Values are retrieved from configuration.
            // Ex. https://login.microsoftonline.com/tfp/{your B2C tenant}.onmicrosoft.com/{your B2C sign-up signin-in policy name}/v2.0
            //string authority = $"{_configuration.GetValue<string>("AzureADB2C:Instance")}/{_configuration.GetValue<string>("AzureADB2C:Domain")}/{_configuration.GetValue<string>("AzureADB2C:SignUpSignInPolicyId")}/v2.0";
            string authority = $"{_configuration.GetValue<string>("AzureADB2C:Instance")}tfp/{_configuration.GetValue<string>("AzureADB2C:Domain")}/{_configuration.GetValue<string>("AzureADB2C:SignUpSignInPolicyId")}";

            // Build the redirect Uri
            // Ex. https://localhost:44340/signin-oidc
            string redirectUri = UriHelper.BuildAbsolute(Request.Scheme, Request.Host, _configuration.GetValue <string>("AzureADB2C:CallbackPath"));

            // Reconstruct the token cache based on the signed in User ID and the current HttpContext
            TokenCache userTokenCache = new MSALSessionCache(signedInUserID, this.HttpContext).GetMsalCacheInstance();

            // Create an instance of the ConfidentialClientApplication to retrieve the access token from the cache using
            // the authority, redirectUri, the token cache and the client ID and client secret of the web
            // application (from configuration)
            ConfidentialClientApplication cca = new ConfidentialClientApplication(_configuration.GetValue <string>("AzureADB2C:ClientId"), authority, redirectUri, new ClientCredential(_configuration.GetValue <string>("AzureADB2C:ClientSecret")), userTokenCache, null);

            // Retrieve the cached access token
            var accounts = await cca.GetAccountsAsync();

            try
            {
                AuthenticationResult result = await cca.AcquireTokenSilentAsync(_configuration.GetValue <string>("AzureADB2C:ApiScopes").Split(' '), accounts.FirstOrDefault(), authority, false);

                accessToken = result.AccessToken;
            }
            catch (Exception)
            {
                // The token was not found in the cache, force a sign out of the user
                // so they must re-authenticate
                await HttpContext.SignOutAsync();
            }

            return(accessToken);
        }
예제 #21
0
        // Gets an access token. First tries to get the token from the token cache.
        public async Task <string> GetUserAccessTokenAsync()
        {
            string             signedInUserID = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
            HttpContextWrapper httpContext    = new HttpContextWrapper(HttpContext.Current);
            TokenCache         userTokenCache = new SessionTokenCache(signedInUserID, httpContext).GetMsalCacheInstance();
            //var cachedItems = tokenCache.ReadItems(appId); // see what's in the cache

            ConfidentialClientApplication cca = new ConfidentialClientApplication(
                appId,
                redirectUri,
                new ClientCredential(appSecret),
                userTokenCache,
                null);

            try
            {
                IEnumerable <IAccount> accounts = await cca.GetAccountsAsync();

                IAccount             firstAccount = accounts.FirstOrDefault();
                AuthenticationResult result       = await cca.AcquireTokenSilentAsync(scopes.Split(new char[] { ' ' }), firstAccount);

                return(result.AccessToken);
            }

            // Unable to retrieve the access token silently.
            catch (Exception)
            {
                HttpContext.Current.Request.GetOwinContext().Authentication.Challenge(
                    new AuthenticationProperties()
                {
                    RedirectUri = "/"
                },
                    OpenIdConnectAuthenticationDefaults.AuthenticationType);

                throw new ServiceException(
                          new Error
                {
                    Code    = GraphErrorCode.AuthenticationFailure.ToString(),
                    Message = Resource.Error_AuthChallengeNeeded,
                });
            }
        }
        public async Task <ActionResult> ReadMail()
        {
            try
            {
                string     signedInUserID = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
                TokenCache userTokenCache = new MSALSessionCache(signedInUserID, this.HttpContext).GetMsalCacheInstance();

                ConfidentialClientApplication cca =
                    new ConfidentialClientApplication(clientId, redirectUri, new ClientCredential(appKey), userTokenCache, null);
                var accounts = await cca.GetAccountsAsync();

                if (accounts.Any())
                {
                    string[]             scopes = { "Mail.Read" };
                    AuthenticationResult result = await cca.AcquireTokenSilentAsync(scopes, accounts.First());

                    HttpClient hc = new HttpClient();
                    hc.DefaultRequestHeaders.Authorization =
                        new System.Net.Http.Headers.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;
                }
                else
                {
                }
                return(View());
            }
            catch (MsalUiRequiredException)
            {
                ViewBag.Relogin = "******";
                return(View());
            }
            catch (Exception eee)
            {
                ViewBag.Error = "An error has occurred. Details: " + eee.Message;
                return(View());
            }
        }
        // Gets an access token. First tries to get the access token from the token cache.
        // Using password (secret) to authenticate. Production apps should use a certificate.
        public async Task <string> GetUserAccessTokenAsync(string userId)
        {
            _userTokenCache = new SessionTokenCache(userId, _memoryCache).GetCacheInstance();

            var cca = new ConfidentialClientApplication(
                _appId,
                _redirectUri,
                _credential,
                _userTokenCache,
                null);

            var accounts = (await cca.GetAccountsAsync()).ToList();

            if (!accounts.Any())
            {
                throw new ServiceException(new Error
                {
                    Code    = "TokenNotFound",
                    Message = "User not found in token cache. Maybe the server was restarted."
                });
            }

            try
            {
                var result = await cca.AcquireTokenSilentAsync(_scopes, accounts.First());

                return(result.AccessToken);
            }

            // Unable to retrieve the access token silently.
            catch (Exception)
            {
                throw new ServiceException(new Error
                {
                    Code    = GraphErrorCode.AuthenticationFailure.ToString(),
                    Message = "Caller needs to authenticate. Unable to retrieve the access token silently."
                });
            }
        }
        /// <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="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>
        private async Task <string> GetAccessTokenOnBehalfOfUser(ConfidentialClientApplication application, string accountIdentifier, IEnumerable <string> scopes, string loginHint)
        {
            if (accountIdentifier == null)
            {
                throw new ArgumentNullException(nameof(accountIdentifier));
            }

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

            // Get the account
            IAccount account = await application.GetAccountAsync(accountIdentifier);

            // Special case for guest users as the Guest iod / tenant id are not surfaced.
            if (account == null)
            {
                var accounts = await application.GetAccountsAsync();

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

            try
            {
                AuthenticationResult result = null;
                result = await application.AcquireTokenSilentAsync(scopes.Except(scopesRequestedByMsalNet), account);

                return(result.AccessToken);
            }
            catch (MsalException)
            {
                // TODO process the exception see if this is retryable etc ...
                throw;
            }
        }
예제 #25
0
        public async Task <IActionResult> OnGetAsync()
        {
            string responseString = "";

            try
            {
                // Retrieve the token with the specified scopes
                var scope = _azureAdB2COptions.ApiScopes.Split(' ');

                string signedInUserID = HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value;

                var userTokenCache = new MSALSessionCache(
                    signedInUserID,
                    this.HttpContext).GetMsalCacheInstance();

                var cca =
                    new ConfidentialClientApplication(
                        _azureAdB2COptions.ClientId,
                        _azureAdB2COptions.Authority,
                        _azureAdB2COptions.RedirectUri,
                        new ClientCredential(_azureAdB2COptions.ClientSecret),
                        userTokenCache,
                        null);

                var accounts =
                    await cca.GetAccountsAsync();

                var result =
                    await cca.AcquireTokenSilentAsync(scope, accounts.FirstOrDefault(), _azureAdB2COptions.Authority, false);

                var client  = new HttpClient();
                var request = new HttpRequestMessage(
                    HttpMethod.Get,
                    _azureAdB2COptions.ApiUrl + "/secure");

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

                ViewData["AuthenticationResultAccessToken"] = result.AccessToken;
                ViewData["AuthenticationResultIdToken"]     = result.IdToken;
                ViewData["AuthenticationResultTenantId"]    = result.TenantId;
                ViewData["AuthenticationResultScopes"]      = JsonConvert.SerializeObject(result.Scopes, Formatting.Indented);
                ViewData["AuthenticationResultUser"]        = JsonConvert.SerializeObject(result.Account, Formatting.Indented);
                ViewData["AzureAdB2COptionsClientId"]       = _azureAdB2COptions.ClientId;
                ViewData["AzureAdB2COptionsAuthority"]      = _azureAdB2COptions.Authority;
                ViewData["AzureAdB2COptionsRedirectUri"]    = _azureAdB2COptions.RedirectUri;
                ViewData["AzureAdB2COptionsClientSecret"]   = _azureAdB2COptions.ClientSecret;
                ViewData["AzureAdB2COptionsApiUrl"]         = _azureAdB2COptions.ApiUrl;
                ViewData["AzureAdB2COptionsApiScopes"]      = _azureAdB2COptions.ApiScopes;

                // 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["ResponsePayload"] = $"{responseString}";

            return(Page());
        }
예제 #26
0
        // Gets an access token and its expiration date. First tries to get the token from the token cache.
        public async Task <string> GetUserAccessTokenAsync()
        {
            // Initialize the cache.
            HttpContextBase context = HttpContext.Current.GetOwinContext().Environment["System.Web.HttpContextBase"] as HttpContextBase;

            tokenCache = new SessionTokenCache(
                ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value,
                context).GetMsalCacheInstance();
            //var cachedItems = tokenCache.ReadItems(appId); // see what's in the cache

            if (!redirectUri.EndsWith("/"))
            {
                redirectUri = redirectUri + "/";
            }
            string[] segments = context.Request.Path.Split(new char[] { '/' });
            ConfidentialClientApplication cca = new ConfidentialClientApplication(
                appId,
                redirectUri + segments[1],
                new ClientCredential(appSecret),
                tokenCache,
                null);
            bool?isAdmin  = HttpContext.Current.Session["IsAdmin"] as bool?;
            var  accounts = await cca.GetAccountsAsync();

            string allScopes = nonAdminScopes;

            if (isAdmin.GetValueOrDefault())
            {
                allScopes += " " + adminScopes;
            }
            if (accounts.Any())
            {
                string[] scopes = allScopes.Split(new char[] { ' ' });
                try
                {
                    AuthenticationResult result = await cca.AcquireTokenSilentAsync(scopes, accounts.First());

                    return(result.AccessToken);
                }

                // Unable to retrieve the access token silently.
                catch (Exception)
                {
                    HttpContext.Current.Request.GetOwinContext().Authentication.Challenge(
                        new AuthenticationProperties()
                    {
                        RedirectUri = redirectUri + segments[1]
                    },
                        OpenIdConnectAuthenticationDefaults.AuthenticationType);

                    throw new ServiceException(
                              new Error
                    {
                        Code    = GraphErrorCode.AuthenticationFailure.ToString(),
                        Message = Resource.Error_AuthChallengeNeeded,
                    });
                }
            }
            else
            {
                return("No access token to return check in SampleAuthProvider.cs");
            }
        }
        public async Task <ActionResult> CreateSubscription()
        {
            string subscriptionsEndpoint = "https://graph.microsoft.com/v1.0/subscriptions/";

            // This sample subscribes to get notifications when the user receives an email.
            HttpClient client = new HttpClient();

            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, subscriptionsEndpoint);

            Subscription subscription = new Subscription
            {
                Resource        = "me/mailFolders('Inbox')/messages",
                ChangeType      = "created",
                NotificationUrl = ConfigurationManager.AppSettings["ida:NotificationUrl"],
                ClientState     = Guid.NewGuid().ToString(),
                //ExpirationDateTime = DateTime.UtcNow + new TimeSpan(0, 0, 4230, 0) // current maximum time span for messages
                ExpirationDateTime = DateTime.UtcNow + new TimeSpan(0, 0, 15, 0) // shorter duration useful for testing
            };

            string contentString = JsonConvert.SerializeObject(subscription,
                                                               new JsonSerializerSettings {
                NullValueHandling = NullValueHandling.Ignore
            });

            request.Content = new StringContent(contentString, System.Text.Encoding.UTF8, "application/json");

            // try to get token silently
            string     signedInUserID         = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
            TokenCache userTokenCache         = new MSALSessionCache(signedInUserID, this.HttpContext).GetMsalCacheInstance();
            ConfidentialClientApplication cca = new ConfidentialClientApplication(clientId, redirectUri, new ClientCredential(appKey), userTokenCache, null);
            var accounts = await cca.GetAccountsAsync();

            if (accounts.Any())
            {
                string[] scopes = { "Mail.Read" };
                try
                {
                    AuthenticationResult result = await cca.AcquireTokenSilentAsync(scopes, accounts.First());

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

                    if (response.IsSuccessStatusCode)
                    {
                        ViewBag.AuthorizationRequest = null;
                        string stringResult = await response.Content.ReadAsStringAsync();

                        SubscriptionViewModel viewModel = new SubscriptionViewModel
                        {
                            Subscription = JsonConvert.DeserializeObject <Subscription>(stringResult)
                        };

                        // This sample temporarily stores the current subscription ID, client state, user object ID, and tenant ID.
                        // This info is required so the NotificationController, which is not authenticated, can retrieve an access token from the cache and validate the subscription.
                        // Production apps typically use some method of persistent storage.
                        SubscriptionStore.SaveSubscriptionInfo(viewModel.Subscription.Id,
                                                               viewModel.Subscription.ClientState,
                                                               ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier")?.Value,
                                                               ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid")?.Value);

                        // This sample just saves the current subscription ID to the session so we can delete it later.
                        Session["SubscriptionId"] = viewModel.Subscription.Id;
                        return(View("Subscription", viewModel));
                    }
                }
                catch (MsalUiRequiredException)
                {
                    try
                    {// when failing, manufacture the URL and assign it
                        string authReqUrl = await WebApp.Utils.OAuth2RequestManager.GenerateAuthorizationRequestUrl(scopes, cca, this.HttpContext, Url);

                        ViewBag.AuthorizationRequest = authReqUrl;
                    }
                    catch (Exception ee)
                    {
                        Response.Write(ee.Message);
                    }
                }
            }
            else
            {
            }
            return(View("Subscription", null));
        }
예제 #28
0
        public async Task <string> GetAccessToken()
        {
            string accessToken = null;

            // Load the app config from web.config
            string appId       = ConfigurationManager.AppSettings["ida:AppId"];
            string appPassword = ConfigurationManager.AppSettings["ida:AppPassword"];
            string redirectUri = ConfigurationManager.AppSettings["ida:RedirectUri"];

            string[] scopes = ConfigurationManager.AppSettings["ida:AppScopes"]
                              .Replace(' ', ',').Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

            // Get the current user's ID
            string userId = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;

            if (!string.IsNullOrEmpty(userId))
            {
                // Get the user's token cache
                SessionTokenCache tokenCache = new SessionTokenCache(userId, HttpContext);

                ConfidentialClientApplication cca = new ConfidentialClientApplication(
                    appId, redirectUri, new ClientCredential(appPassword), tokenCache.GetMsalCacheInstance(), null);

                // Call AcquireTokenSilentAsync, which will return the cached
                // access token if it has not expired. If it has expired, it will
                // handle using the refresh token to get a new one.
                AuthenticationResult result = await cca.AcquireTokenSilentAsync(scopes, cca.GetAccountsAsync().Result.First());

                accessToken = result.AccessToken;
            }

            return(accessToken);
        }
        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");

            request.Content = new StringContent(message, Encoding.UTF8, "application/json");

            // try to get token silently
            string     signedInUserID         = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;
            TokenCache userTokenCache         = new MSALSessionCache(signedInUserID, this.HttpContext).GetMsalCacheInstance();
            ConfidentialClientApplication cca = new ConfidentialClientApplication(clientId, redirectUri, new ClientCredential(appKey), userTokenCache, null);
            var accounts = await cca.GetAccountsAsync();

            if (accounts.Any())
            {
                string[] scopes = { "Mail.Send" };
                try
                {
                    AuthenticationResult result = await cca.AcquireTokenSilentAsync(scopes, accounts.First());

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

                    if (response.IsSuccessStatusCode)
                    {
                        ViewBag.AuthorizationRequest = null;
                        return(View("MailSent"));
                    }
                }
                catch (MsalUiRequiredException)
                {
                    try
                    {// when failing, manufacture the URL and assign it
                        string authReqUrl = await WebApp.Utils.OAuth2RequestManager.GenerateAuthorizationRequestUrl(scopes, cca, this.HttpContext, Url);

                        ViewBag.AuthorizationRequest = authReqUrl;
                    }
                    catch (Exception ee)
                    {
                        Response.Write(ee.Message);
                    }
                }
            }
            else
            {
            }
            return(View());
        }