/// <summary> /// Logs the user into Office 365. /// </summary> /// <param name="authState">The login or logout status of the user.</param> /// <returns>A redirect to the Office 365 login page.</returns> public async Task <ActionResult> Login(string authState) { if (string.IsNullOrEmpty(Settings.AzureADClientId) || string.IsNullOrEmpty(Settings.AzureADClientSecret)) { ViewBag.Message = "Please set your client ID and client secret in the Web.config file"; return(View()); } ConfidentialClientApplicationBuilder clientBuilder = ConfidentialClientApplicationBuilder.Create(Settings.AzureADClientId); ConfidentialClientApplication clientApp = (ConfidentialClientApplication)clientBuilder.Build(); // Generate the parameterized URL for Azure login. string[] graphScopes = { "Files.Read.All", "User.Read" }; var urlBuilder = clientApp.GetAuthorizationRequestUrl(graphScopes); urlBuilder.WithRedirectUri(loginRedirectUri.ToString()); urlBuilder.WithAuthority(Settings.AzureADAuthority); urlBuilder.WithExtraQueryParameters("state=" + authState); var authUrl = await urlBuilder.ExecuteAsync(System.Threading.CancellationToken.None); // Redirect the browser to the login page, then come back to the Authorize method below. return(Redirect(authUrl.ToString())); }
public async Task ClientCreds_NonExpired_NeedsRefresh_AADUnavailableResponse_Async() { // Arrange using (MockHttpAndServiceBundle harness = base.CreateTestHarness()) { Trace.WriteLine("1. Setup an app with a token cache with one AT"); ConfidentialClientApplication app = SetupCca(harness); Trace.WriteLine("2. Configure AT so that it shows it needs to be refreshed"); UpdateATWithRefreshOn(app.AppTokenCacheInternal.Accessor, DateTime.UtcNow - TimeSpan.FromMinutes(1)); TokenCacheAccessRecorder cacheAccess = app.AppTokenCache.RecordAccess(); Trace.WriteLine("3. Configure AAD to respond with an error"); harness.HttpManager.AddAllMocks(TokenResponseType.Invalid_AADUnavailable503); harness.HttpManager.AddTokenResponse(TokenResponseType.Invalid_AADUnavailable503); // Act AuthenticationResult result = await app.AcquireTokenForClient(TestConstants.s_scope) .ExecuteAsync() .ConfigureAwait(false); // Assert Assert.IsNotNull(result, "ClientCreds should still succeeds even though AAD is unavaible"); Assert.AreEqual(0, harness.HttpManager.QueueSize); cacheAccess.AssertAccessCounts(1, 0); // the refresh failed, no new data is written to the cache // Now let AAD respond with tokens harness.HttpManager.AddTokenResponse(TokenResponseType.Valid); result = await app.AcquireTokenForClient(TestConstants.s_scope) .ExecuteAsync() .ConfigureAwait(false); Assert.IsNotNull(result); cacheAccess.AssertAccessCounts(2, 1); // new tokens written to cache } }
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.Read" }; try { AuthenticationResult result = await cca.AcquireTokenSilentAsync(scopes, accounts.First()); } catch (MsalUiRequiredException) { try { // when failing, manufacture the URL and assign it string authReqUrl = await Calendar_OneDrive_Mail_Graph.Utils.OAuth2RequestManager.GenerateAuthorizationRequestUrl(scopes, cca, this.HttpContext, Url); ViewBag.AuthorizationRequest = authReqUrl; } catch (Exception ex) { Response.Write(ex.Message); } } } else { } return(View()); }
public async Task<ActionResult> Delete(string id) { try { // Retrieve the token with the specified scopes var scope = new string[] { Startup.WriteTasksScope }; string signedInUserID = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value; TokenCache userTokenCache = new MSALSessionCache(signedInUserID, this.HttpContext).GetMsalCacheInstance(); ConfidentialClientApplication cca = new ConfidentialClientApplication(Startup.ClientId, Startup.Authority, Startup.RedirectUri, new ClientCredential(Startup.ClientSecret), userTokenCache, null); AuthenticationResult result = await cca.AcquireTokenSilentAsync(scope, cca.Users.FirstOrDefault(), Startup.Authority, false); HttpClient client = new HttpClient(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Delete, apiEndpoint + id); // Add token to the Authorization header and send 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: case HttpStatusCode.NoContent: return new RedirectResult("/Tasks"); case HttpStatusCode.Unauthorized: return ErrorAction("Please sign in again. " + response.ReasonPhrase); default: return ErrorAction("Error. Status code = " + response.StatusCode); } } catch (Exception ex) { return ErrorAction("Error deleting from list: " + ex.Message); } }
public async Task JsonWebTokenWithX509PublicCertSendCertificateTestAsync() { using (var httpManager = new MockHttpManager()) { var serviceBundle = ServiceBundle.CreateWithCustomHttpManager(httpManager); SetupMocks(httpManager); var certificate = new X509Certificate2( ResourceHelper.GetTestResourceRelativePath("valid_cert.pfx"), MsalTestConstants.DefaultPassword); var clientAssertion = new ClientAssertionCertificate(certificate); var clientCredential = new ClientCredential(clientAssertion); var app = new ConfidentialClientApplication( serviceBundle, MsalTestConstants.ClientId, ClientApplicationBase.DefaultAuthority, MsalTestConstants.RedirectUri, clientCredential, _cache, _cache) { ValidateAuthority = false }; //Check for x5c claim httpManager.AddMockHandler(X5CMockHandler); AuthenticationResult result = await(app as IConfidentialClientApplicationWithCertificate).AcquireTokenForClientWithCertificateAsync( MsalTestConstants.Scope).ConfigureAwait(false); Assert.IsNotNull(result.AccessToken); result = await app.AcquireTokenForClientAsync(MsalTestConstants.Scope).ConfigureAwait(false); Assert.IsNotNull(result.AccessToken); } }
/// <summary> /// Gets the current user's access token from the MSAL token cache. /// </summary> /// <returns>An access token</returns> public async Task <string> GetUserAccessTokenAsync() { string userId = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value; HttpContextWrapper httpContext = new HttpContextWrapper(HttpContext.Current); TokenCache userTokenCache = new SessionTokenCache(userId, httpContext).GetMsalCacheInstance(); ConfidentialClientApplication cca = new ConfidentialClientApplication( clientId, redirectUri, new ClientCredential(clientSecret), userTokenCache, null); // Attempt to retrieve access token from the cache. Could also make a network call for a new // access token if the cached one is expired or close to expiration and a refresh token is // available. try { AuthenticationResult result = await cca.AcquireTokenSilentAsync( scopes.Split(new char[] { ' ' }), cca.Users.First()); 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 Microsoft.Graph.ServiceException( new Microsoft.Graph.Error { Code = Microsoft.Graph.GraphErrorCode.AuthenticationFailure.ToString(), Message = "Authentication is required." }); } }
public async Task ClientCreds_NonExpired_NeedsRefresh_AADInvalidResponse_Async() { bool wasErrorLogged = false; // Arrange using (MockHttpAndServiceBundle harness = base.CreateTestHarness()) { Trace.WriteLine("1. Setup an app"); ConfidentialClientApplication app = SetupCca(harness, LocalLogCallback); Trace.WriteLine("2. Configure AT so that it shows it needs to be refreshed"); UpdateATWithRefreshOn(app.AppTokenCacheInternal.Accessor); TokenCacheAccessRecorder cacheAccess = app.AppTokenCache.RecordAccess(); Trace.WriteLine("3. Configure AAD to respond with the typical Invalid Grant error"); harness.HttpManager.AddAllMocks(TokenResponseType.InvalidGrant); // Act await app.AcquireTokenForClient(TestConstants.s_scope) .ExecuteAsync() .ConfigureAwait(false); Assert.IsTrue(YieldTillSatisfied(() => wasErrorLogged == true)); cacheAccess.WaitTo_AssertAcessCounts(1, 0); } void LocalLogCallback(LogLevel level, string message, bool containsPii) { if (level == LogLevel.Error && message.Contains(BackgroundFetch_Failed)) { wasErrorLogged = true; } } }
public async Task ClientCreds_OnBehalfOf_NonExpired_NeedsRefresh_ValidResponse_Async() { // Arrange using (MockHttpAndServiceBundle harness = base.CreateTestHarness()) { Trace.WriteLine("1. Setup an app with a token cache with one AT"); ConfidentialClientApplication app = SetupCca(harness); Trace.WriteLine("2. Configure AT so that it shows it needs to be refreshed"); var refreshOn = UpdateATWithRefreshOn(app.UserTokenCacheInternal.Accessor).RefreshOn; TokenCacheAccessRecorder cacheAccess = app.UserTokenCache.RecordAccess(); Trace.WriteLine("3. Configure AAD to respond with valid token to the refresh RT flow"); harness.HttpManager.AddAllMocks(TokenResponseType.Valid_UserFlows); // Act Trace.WriteLine("4. ATS - should perform an RT refresh"); AuthenticationResult result = await app.AcquireTokenOnBehalfOf(TestConstants.s_scope, new UserAssertion(TestConstants.UserAssertion, "assertiontype")) .ExecuteAsync() .ConfigureAwait(false); // Assert YieldTillSatisfied(() => harness.HttpManager.QueueSize == 0); Assert.IsNotNull(result); Assert.AreEqual(0, harness.HttpManager.QueueSize, "MSAL should have refreshed the token because the original AT was marked for refresh"); cacheAccess.WaitTo_AssertAcessCounts(1, 1); Assert.IsTrue(result.AuthenticationResultMetadata.CacheRefreshReason == CacheRefreshReason.ProactivelyRefreshed); Assert.IsTrue(result.AuthenticationResultMetadata.RefreshOn == refreshOn); result = await app.AcquireTokenOnBehalfOf(TestConstants.s_scope, new UserAssertion(TestConstants.UserAssertion, "assertiontype")) .ExecuteAsync() .ConfigureAwait(false); Assert.IsTrue(result.AuthenticationResultMetadata.CacheRefreshReason == CacheRefreshReason.NotApplicable); } }
// 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); if (!cca.Users.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, cca.Users.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." }); } }
public void ConfigureAuth(IAppBuilder app) { ApplicationDbContext db = new ApplicationDbContext(); app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType); app.UseCookieAuthentication(new CookieAuthenticationOptions()); app.UseOpenIdConnectAuthentication( new OpenIdConnectAuthenticationOptions { ClientId = clientId, Authority = Authority, Scope = "openid offline_access profile email " + string.Join(" ", scopes), RedirectUri = postLogoutRedirectUri, PostLogoutRedirectUri = "/", TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters { ValidateIssuer = false }, Notifications = new OpenIdConnectAuthenticationNotifications() { // If there is a code in the OpenID Connect response, redeem it for an access token and refresh token, and store those away. AuthorizationCodeReceived = async(context) => { var code = context.Code; string signedInUserID = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value; ConfidentialClientApplication cca = new ConfidentialClientApplication(clientId, postLogoutRedirectUri, new ClientCredential(appKey), new MSALTokenCache(signedInUserID)); var result = await cca.AcquireTokenByAuthorizationCodeAsync(scopes, code); } } }); }
public void ConstructorsTest() { ConfidentialClientApplication app = new ConfidentialClientApplication(TestConstants.DefaultClientId, TestConstants.DefaultRedirectUri, new ClientCredential(TestConstants.DefaultClientSecret), new TokenCache()); Assert.IsNotNull(app); Assert.IsNotNull(app.UserTokenCache); Assert.IsNotNull(app.AppTokenCache); Assert.AreEqual("https://login.microsoftonline.com/common/", app.Authority); Assert.AreEqual(TestConstants.DefaultClientId, app.ClientId); Assert.AreEqual(TestConstants.DefaultRedirectUri, app.RedirectUri); Assert.AreEqual("https://login.microsoftonline.com/common/", app.Authority); Assert.IsNotNull(app.ClientCredential); Assert.IsNotNull(app.ClientCredential.Secret); Assert.AreEqual(TestConstants.DefaultClientSecret, app.ClientCredential.Secret); Assert.IsNull(app.ClientCredential.Certificate); Assert.IsNull(app.ClientCredential.ClientAssertion); Assert.AreEqual(0, app.ClientCredential.ValidTo); app = new ConfidentialClientApplication(TestConstants.DefaultAuthorityGuestTenant, TestConstants.DefaultClientId, TestConstants.DefaultRedirectUri, new ClientCredential("secret"), new TokenCache()); Assert.AreEqual(TestConstants.DefaultAuthorityGuestTenant, app.Authority); }
public async Task ClientCreds_WithClientAssertion_Adfs_Async() { var cert = await _keyVault.GetCertificateWithPrivateMaterialAsync(AdfsCertName) .ConfigureAwait(false); string clientAssertion = GetSignedClientAssertionUsingWilson(Adfs2019LabConstants.Authority, cert); ConfidentialClientApplication msalConfidentialClient = ConfidentialClientApplicationBuilder.Create(Adfs2019LabConstants.ConfidentialClientId) .WithAdfsAuthority(Adfs2019LabConstants.Authority, true) .WithRedirectUri(Adfs2019LabConstants.ClientRedirectUri) .WithClientAssertion(clientAssertion) .BuildConcrete(); AuthenticationResult authResult = await msalConfidentialClient .AcquireTokenForClient(s_adfsScopes) .ExecuteAsync() .ConfigureAwait(false); Assert.IsNotNull(authResult); Assert.IsNotNull(authResult.AccessToken); Assert.IsNull(authResult.IdToken); }
/// <summary> /// Get access token for azure active directory application with scope for this application /// </summary> /// <returns>access token for azure active directory application</returns> private async Task <AuthResult> GetAccessTokenForApplicationAsync(string appId, string appSecret, string tenantId, string redirectUri) { AuthResult result = new AuthResult(); try { ConfidentialClientApplication clientApp = new ConfidentialClientApplication( appId, $"https://login.microsoftonline.com/{tenantId}/v2.0", redirectUri, new ClientCredential(appSecret), null, new TokenCache()); AuthenticationResult authResult = await clientApp.AcquireTokenForClientAsync(new string[] { "https://graph.microsoft.com/.default" }); result.AccessToken = authResult?.AccessToken; } catch (Exception err) { result.Exception = err; } return(result); }
// Gets an access token. First tries to get the token from the token cache. public async Task <string> GetApplicationTokenAsync() { HttpContextWrapper httpContext = new HttpContextWrapper(HttpContext.Current); ConfidentialClientApplication cca = new ConfidentialClientApplication( appId, redirectUri, new ClientCredential(appSecret), null, null); try { AuthenticationResult result = await cca.AcquireTokenForClientAsync(scopes.Split(new char[] { ' ' })); 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, }); } }
private static async Task RunObo_Async(MockHttpManager httpManager, ConfidentialClientApplication app) { httpManager.AddSuccessTokenResponseMockHandlerForPost(); UserAssertion userAssertion = new UserAssertion(TestConstants.DefaultAccessToken); var result = await app.AcquireTokenOnBehalfOf(TestConstants.s_scope, userAssertion).ExecuteAsync().ConfigureAwait(false); Assert.AreEqual(TokenSource.IdentityProvider, result.AuthenticationResultMetadata.TokenSource); // get AT from cache result = await app.AcquireTokenOnBehalfOf(TestConstants.s_scope, userAssertion).ExecuteAsync().ConfigureAwait(false); Assert.AreEqual(TokenSource.Cache, result.AuthenticationResultMetadata.TokenSource); // get AT via OBO flow (no RT cached for OBO) TokenCacheHelper.ExpireAllAccessTokens(app.UserTokenCacheInternal); var handler = httpManager.AddSuccessTokenResponseMockHandlerForPost(); handler.ExpectedPostData = new Dictionary <string, string> { { OAuth2Parameter.GrantType, OAuth2GrantType.JwtBearer } }; result = await app.AcquireTokenOnBehalfOf(TestConstants.s_scope, userAssertion).ExecuteAsync().ConfigureAwait(false); Assert.AreEqual(TokenSource.IdentityProvider, result.AuthenticationResultMetadata.TokenSource); }
// 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 result = await client.AcquireTokenSilentAsync(new[] { $"{authOptions.ApiIdentifier}/read_values" }, client.Users.FirstOrDefault()); return(result.AccessToken); } catch (MsalUiRequiredException) { throw new ReauthenticationRequiredException(); } }
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); // 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(' '), idClient.Users.First()); requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken); }))); }
public async Task <string> GetAccessToken(HttpContextBase httpContextBase) { string accessToken = null; // Load the app config from web.config var appId = ConfigurationManager.AppSettings["ida:AppId"]; var appPassword = ConfigurationManager.AppSettings["ida:AppPassword"]; var redirectUri = ConfigurationManager.AppSettings["ida:RedirectUri"]; var scopes = ConfigurationManager.AppSettings["ida:AppScopes"] .Replace(' ', ',').Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); // Get the current user's ID var userId = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value; if (!string.IsNullOrEmpty(userId)) { // Get the user's token cache var tokenCache = new SessionTokenCache(userId, httpContextBase); var confidentialClientApplication = 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. var result = await confidentialClientApplication.AcquireTokenSilentAsync(scopes, confidentialClientApplication.Users.First()); accessToken = result.AccessToken; } return(accessToken); }
/// <summary> /// A helper method to create a ConfidentialClientApplication /// required to retrieve the token that is needed to be attached /// as a Bearer Token to a Request. /// <para> /// This code is for an AAD (it's using AuthenticationUri, rather than .AuthorityCookieConfigurationPolicyUri) /// </para> /// </summary> public ConfidentialClientApplication CreateConfidentialClientApplication( HttpContextBase httpContextBase, string authorityUriOverride, IOidcSettingsConfidentialClientConfiguration oidcSettingsConfidentialClientConfiguration, params string[] fqScopes) { // ** IMPORTANT** // The calls to AAD and B2C are mostly the same bar the following: // For AAD, use .AuthorityUri var authorityUri = authorityUriOverride ?? oidcSettingsConfidentialClientConfiguration.AuthorityUri; var signedInUserIdentifier = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value; var userTokenCache = new MSALSessionCache(signedInUserIdentifier, httpContextBase).GetMsalCacheInstance(); TokenCache appTokenCache = null; var confidentialClientApplication = new ConfidentialClientApplication( oidcSettingsConfidentialClientConfiguration.ClientId, authorityUri /*note...*/, oidcSettingsConfidentialClientConfiguration.ClientRedirectUri, new ClientCredential(oidcSettingsConfidentialClientConfiguration.ClientSecret), userTokenCache, appTokenCache); return(confidentialClientApplication); }
public async Task ClientCreds_NonExpired_NeedsRefresh_AADInvalidResponse_Async() { // Arrange using (MockHttpAndServiceBundle harness = base.CreateTestHarness()) { Trace.WriteLine("1. Setup an app with a token cache with one AT"); ConfidentialClientApplication app = SetupCca(harness); Trace.WriteLine("2. Configure AT so that it shows it needs to be refreshed"); UpdateATWithRefreshOn(app.AppTokenCacheInternal.Accessor, DateTime.UtcNow - TimeSpan.FromMinutes(1)); TokenCacheAccessRecorder cacheAccess = app.AppTokenCache.RecordAccess(); Trace.WriteLine("3. Configure AAD to respond with the typical Invalid Grant error"); AddHttpMocks(TokenResponseType.Invalid_AADAvailable, harness.HttpManager, pca: false); // Act await AssertException.TaskThrowsAsync <MsalUiRequiredException>(() => app.AcquireTokenForClient(TestConstants.s_scope) .ExecuteAsync()) .ConfigureAwait(false); cacheAccess.AssertAccessCounts(1, 0); } }
public async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedContext context) { // Use MSAL to swap the code for an access token // Extract the code from the response notification var code = context.ProtocolMessage.Code; string signedInUserID = context.Principal.FindFirst(ClaimTypes.NameIdentifier).Value; TokenCache userTokenCache = new MSALSessionCache(signedInUserID, context.HttpContext).GetMsalCacheInstance(); ConfidentialClientApplication cca = new ConfidentialClientApplication(AzureAdB2COptions.ClientId, AzureAdB2COptions.Authority, AzureAdB2COptions.RedirectUri, new ClientCredential(AzureAdB2COptions.ClientSecret), userTokenCache, null); cca.ValidateAuthority = false; try { AuthenticationResult result = await cca.AcquireTokenByAuthorizationCodeAsync(code, AzureAdB2COptions.ApiScopes.Split(' ')); context.HandleCodeRedemption(result.AccessToken, result.IdToken); } catch (Exception ex) { //TODO: Handle throw; } }
/// <summary> /// Generate a certificate. Create a Confidential Client Application with that certificate and /// an AcquireTokenForClient call to benchmark. /// </summary> public CryptoManagerTests() { _httpManager = new MockHttpManager(); _httpManager.MessageHandlerFunc = () => new MockHttpMessageHandler() { ExpectedMethod = HttpMethod.Post, ResponseMessage = MockHelpers.CreateSuccessfulClientCredentialTokenResponseMessage() }; _requests = new AcquireTokenForClientParameterBuilder[AppsCount]; for (int i = 0; i < AppsCount; i++) { X509Certificate2 certificate = CreateCertificate("CN=rsa2048", RSA.Create(2048), HashAlgorithmName.SHA256, null); _cca = ConfidentialClientApplicationBuilder .Create(TestConstants.ClientId) .WithAuthority(new Uri(TestConstants.AuthorityTestTenant)) .WithRedirectUri(TestConstants.RedirectUri) .WithCertificate(certificate) .WithHttpManager(_httpManager) .BuildConcrete(); AddHostToInstanceCache(_cca.ServiceBundle, TestConstants.ProductionPrefNetworkEnvironment); _requests[_requestIdx] = _cca.AcquireTokenForClient(TestConstants.s_scope) .WithForceRefresh(true); } }
public async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedContext context, string clientId, string authority, string clientSecret, string redirectUri, string apiScopes) { // Use MSAL to swap the code for an access token // Extract the code from the response notification var code = context.ProtocolMessage.Code; var signedInUserId = context.Principal.FindFirst(ClaimTypes.NameIdentifier).Value; var userTokenCache = new MsalSessionCache(signedInUserId, context.HttpContext).GetMsalCacheInstance(); var cca = new ConfidentialClientApplication(clientId, authority, redirectUri, new ClientCredential(clientSecret), userTokenCache, null); try { var result = await cca.AcquireTokenByAuthorizationCodeAsync(code, apiScopes.Split(' ')); context.HandleCodeRedemption(result.AccessToken, result.IdToken); } catch (Exception ex) { //TODO: Handle throw; } }
// 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 { var accounts = await cca.GetAccountsAsync(); AuthenticationResult result = await cca.AcquireTokenSilentAsync(scopes.Split(new char[] { ' ' }), accounts.First()); 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 Exception("Caller needs to authenticate."); } }
/// <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 MsalAuthenticationProvider(ConfidentialClientApplication clientApplication, string[] scopes) { _clientApplication = clientApplication; _scopes = scopes; }
public static async Task <string> GenerateAuthorizationRequestUrl(string[] scopes, ConfidentialClientApplication cca, HttpContextBase httpcontext, UrlHelper url) { string signedInUserID = ClaimsPrincipal.Current.FindFirst(System.IdentityModel.Claims.ClaimTypes.NameIdentifier).Value; string preferredUsername = ClaimsPrincipal.Current.FindFirst("upn").Value; Uri oauthCodeProcessingPath = new Uri(httpcontext.Request.Url.GetLeftPart(UriPartial.Authority).ToString()); string state = GenerateState(httpcontext.Request.Url.ToString(), httpcontext, url, scopes); string tenantID = ClaimsPrincipal.Current.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value; string domain_hint = (tenantID == "9188040d-6c67-4c5b-b112-36a304b66dad") ? "consumers" : "organizations"; Uri authzMessageUri = await cca.GetAuthorizationRequestUrlAsync( scopes, oauthCodeProcessingPath.ToString(), preferredUsername, state == null?null : "&state=" + state + "&domain_hint=" + domain_hint, null, // TODo change cca.Authority ); return(authzMessageUri.ToString()); }
/* * Callback function when an authorization code is received */ private async Task OnAuthorizationCodeReceived(AuthorizationCodeReceivedNotification notification) { notification.AuthenticationTicket.Properties.ExpiresUtc = DateTime.UtcNow.AddMinutes(AuthTicketExpiresInMinutes); notification.AuthenticationTicket.Properties.AllowRefresh = AuthTicketAllowRefresh; HttpContext.Current.User = new ClaimsPrincipal(notification.AuthenticationTicket.Identity); // Extract the code from the response notification var code = notification.Code; string signedInUserId = notification.AuthenticationTicket.Identity.FindFirst("userId").Value; //ClaimTypes.NameIdentifier).Value; TokenCache userTokenCache = new MSALSessionCache(signedInUserId, notification.OwinContext.Environment["System.Web.HttpContextBase"] as HttpContextBase).GetMsalCacheInstance(); //CacheFactoryFunc().Invoke();// //TokenCache userTokenCache = new MSALSessionCache(signedInUserID, notification.OwinContext.Environment["System.Web.HttpContextBase"] as HttpContextBase).GetMsalCacheInstance(); ConfidentialClientApplication context = new ConfidentialClientApplication(ClientId, Authority, RedirectUri, new ClientCredential(ClientSecret), userTokenCache, null); AuthenticationResult user = await context.AcquireTokenByAuthorizationCodeAsync(code, new[] { Scopes }); //HttpContext.Current.GetOwinContext().Environment["System.Web.HttpContextBase"] = notification.OwinContext.Environment["System.Web.HttpContextBase"]; //check policy string fullPatch = notification.AuthenticationTicket.Properties.RedirectUri; string tenantName = fullPatch.Split('/').Where(x => x.Length > 0).ToList()[2]; Tenant tenant = _dbContext.Tenants.FirstOrDefault(x => x.DomainName.ToLower() == tenantName.ToLower()); if (tenant == null) { return; } if (tenant.DomainName.ToLower() == "Admin".ToLower()) { _serviceId = ConfigurationManager.AppSettings["ServiceId"]; } else { TenantInfo tenantInfo = _dbContext.TenantInfos.FirstOrDefault(x => x.TenantId == tenant.Id && x.Key == "MyDNVGLServiceId"); if (tenantInfo != null && !string.IsNullOrEmpty(tenantInfo.Value)) { _serviceId = tenantInfo.Value; } } if (string.IsNullOrEmpty(_serviceId)) { return; } var policy = new Policy(); try { policy = await _veracityApiHelper.GetPolicyModel(user.AccessToken, _serviceId); } catch { notification.OwinContext.Authentication.SignOut(); return; } if ((HttpStatusCode)policy.statusCode == HttpStatusCode.NoContent) { //add local roles var ctx = HttpContext.Current.GetOwinContext(); string myDnvglId = ctx.Authentication.User.Claims.FirstOrDefault(x => x.Type == "userId")?.Value; var tenantId = _dbContext.Tenants.FirstOrDefault(x => x.DomainName.ToLower() == tenantName.ToLower())?.Id; AppUser loginedUser = _dbContext.AppUsers.FirstOrDefault(u => u.MyDnvglUserId == myDnvglId && u.TenantId == tenantId); if (loginedUser == null) { return; } var roles = _dbContext.AppUsers.FirstOrDefault(u => u.Id == loginedUser.Id && u.TenantId == loginedUser.TenantId)?.Roles.Select(r => r.RoleId).ToList(); var claims = notification.AuthenticationTicket.Identity; foreach (var role in roles) { claims.AddClaim(new Claim(ClaimTypes.Role, role)); } //Replace claim's 'userId' from MyDnvglId to local UserID claims.RemoveClaim(claims.FindFirst(ClaimTypes.NameIdentifier)); claims.AddClaim(new Claim(ClaimTypes.NameIdentifier, loginedUser.Id)); //add access token into claims claims.AddClaim(new Claim("AccessToken", user.AccessToken)); notification.OwinContext.Authentication.SignIn(new AuthenticationProperties { IsPersistent = true, ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(10) }, claims); } else { notification.OwinContext.Authentication.SignOut(); string strRedirectUrl = policy.url; bool isHaveEmptyRedirectUrl = strRedirectUrl.Split(new string[] { "?", "&" }, StringSplitOptions.None) .Any(x => x.Equals("returnUrl=")); if (isHaveEmptyRedirectUrl) { strRedirectUrl = strRedirectUrl.Replace("returnUrl=", "returnUrl=" + fullPatch); } HttpContext.Current.Response.Redirect(strRedirectUrl); } //AppUser testUser = HttpContext.Current.GetOwinContext().GetUserManager<UserManager<AppUser>>().FindByName(notification.Request.User.GetPowerBIAppAuthenticationIdentity().GetUserName()); //try //{ // //await ClientFactory.CreateClient(RedirectUri).My.ValidatePolicies(); // notification.OwinContext.Authentication.SignIn(notification.AuthenticationTicket.Identity); //} //catch (ServerException ex) //{ // //if (ex.Status == HttpStatusCode.NotAcceptable) // //{ // // notification.Response.Redirect(ex.GetErrorData<ValidationError>().Url); //Getting the redirect url from the error message. // // notification.HandleResponse(); //Mark the notification as handled to allow the redirect to happen. // //} //} }
public void ConfigureAuth(IAppBuilder app) { Debug.WriteLine("Print from configureAuth function in startup_auth.cs"); app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType); app.UseCookieAuthentication(new CookieAuthenticationOptions()); app.UseOAuth2CodeRedeemer( new OAuth2CodeRedeemerOptions { ClientId = appId, ClientSecret = appSecret, RedirectUri = redirectUri } ); app.UseOpenIdConnectAuthentication( new OpenIdConnectAuthenticationOptions { // The `Authority` represents the v2.0 endpoint - https://login.microsoftonline.com/common/v2.0 // The `Scope` describes the permissions that your app will need. See https://azure.microsoft.com/documentation/articles/active-directory-v2-scopes/ ClientId = appId, Authority = String.Format(CultureInfo.InvariantCulture, aadInstance, "common", "/v2.0"), RedirectUri = redirectUri, Scope = scopes, PostLogoutRedirectUri = redirectUri, TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = false, // In a real application you would use IssuerValidator for additional checks, // like making sure the user's organization has signed up for your app. // IssuerValidator = (issuer, token, tvp) => // { // if (MyCustomTenantValidation(issuer)) // return issuer; // else // throw new SecurityTokenInvalidIssuerException("Invalid issuer"); // }, }, Notifications = new OpenIdConnectAuthenticationNotifications { AuthorizationCodeReceived = async(context) => { var code = context.Code; //string signedInUserID = context.AuthenticationTicket.Identity.FindFirst(ClaimTypes.NameIdentifier).Value; string graphScopes = nonAdminScopes; string[] scopes = graphScopes.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); string signedInUserID = System.Web.HttpContext.Current.Session["currentUserId"] as String; ConfidentialClientApplication cca = new ConfidentialClientApplication(appId, redirectUri, new ClientCredential(appSecret), new EFTokenCache(signedInUserID, context.OwinContext.Environment["System.Web.HttpContextBase"] as HttpContextBase).GetMsalCacheInstance(), null); AuthenticationResult result = await cca.AcquireTokenByAuthorizationCodeAsync(code, scopes); context.HandleResponse(); context.Response.Redirect("/Home/ShowMessage?message=" + "Authentication SUCCESSFULLY"); // Check whether the login is from the MSA tenant. // The sample uses this attribute to disable UI buttons for unsupported operations when the user is logged in with an MSA account. //var currentTenantId = context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value; //if (currentTenantId == "9188040d-6c67-4c5b-b112-36a304b66dad") //{ // HttpContext.Current.Session.Add("AccountType", "msa"); //} //// Set IsAdmin session variable to false, since the user hasn't consented to admin scopes yet. //HttpContext.Current.Session.Add("IsAdmin", false); }, AuthenticationFailed = (context) => { context.HandleResponse(); context.Response.Redirect("/Error?message=" + context.Exception.Message); return(Task.FromResult(0)); } } }); }
/// <summary> /// Constructs the configuration properties used to construct a proof of possession request /// </summary> /// <param name="requestUri">An Uri to the protected resource which requires a PoP token. The PoP token will be cryptographically bound to the request uri</param> public PoPAuthenticationConfiguration(Uri requestUri) { ConfidentialClientApplication.GuardMobileFrameworks(); RequestUri = requestUri ?? throw new ArgumentNullException(nameof(requestUri)); }