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"); } }
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); }))); }
/*---------------------------------------------------------------------------- * %%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)); }
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(); } }
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); }
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")); }
/// <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); }
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()); }
/// <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)); }
/// <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; } }
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); }
/// <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); }
// 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; } }
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()); }
// 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)); }
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()); }