private async Task <AuthenticationResult> RefreshAccessTokenAsync(AuthenticationResult result) { AuthenticationResult newResult = null; if (this.Resource != null) { try { newResult = await this.SendTokenRequestByRefreshTokenAsync(result.RefreshToken); this.Authenticator.UpdateTenantId(result.TenantId); if (newResult.IdToken == null) { // If Id token is not returned by token endpoint when refresh token is redeemed, we should copy tenant and user information from the cached token. newResult.UpdateTenantAndUserInfo(result.TenantId, result.IdToken, result.UserInfo); } } catch (AdalException ex) { AdalServiceException serviceException = ex as AdalServiceException; if (serviceException != null && serviceException.ErrorCode == "invalid_request") { throw new AdalServiceException( AdalError.FailedToRefreshToken, AdalErrorMessage.FailedToRefreshToken + ". " + serviceException.Message, (WebException)serviceException.InnerException); } newResult = null; } } return(newResult); }
internal AuthenticationResult LoadFromCache(string authority, string resource, string clientId, TokenSubjectType subjectType, string uniqueId, string displayableId, CallState callState) { Logger.Verbose(callState, "Looking up cache for a token..."); AuthenticationResult result = null; KeyValuePair <TokenCacheKey, AuthenticationResult>?kvp = this.LoadSingleItemFromCache(authority, resource, clientId, subjectType, uniqueId, displayableId, callState); if (kvp.HasValue) { TokenCacheKey cacheKey = kvp.Value.Key; result = kvp.Value.Value; bool tokenNearExpiry = (result.ExpiresOn <= DateTime.UtcNow + TimeSpan.FromMinutes(ExpirationMarginInMinutes)); if (tokenNearExpiry) { result.AccessToken = null; Logger.Verbose(callState, "An expired or near expiry token was found in the cache"); } else if (!cacheKey.ResourceEquals(resource)) { Logger.Verbose(callState, string.Format("Multi resource refresh token for resource '{0}' will be used to acquire token for '{1}'", cacheKey.Resource, resource)); var newResult = new AuthenticationResult(null, null, result.RefreshToken, DateTimeOffset.MinValue); newResult.UpdateTenantAndUserInfo(result.TenantId, result.IdToken, result.UserInfo); result = newResult; } else { Logger.Verbose(callState, string.Format("{0} minutes left until token in cache expires", (result.ExpiresOn - DateTime.UtcNow).TotalMinutes)); } if (result.AccessToken == null && result.RefreshToken == null) { this.tokenCacheDictionary.Remove(cacheKey); Logger.Information(callState, "An old item was removed from the cache"); this.HasStateChanged = true; result = null; } if (result != null) { Logger.Information(callState, "A matching item (access token or refresh token or both) was found in the cache"); } } else { Logger.Information(callState, "No matching token was found in the cache"); } return(result); }
private AuthenticationResultEx GetResultFromBrokerResponse(Bundle bundleResult) { if (bundleResult == null) { throw new AdalException("bundleResult"); } int errCode = bundleResult.GetInt(AccountManager.KeyErrorCode); string msg = bundleResult.GetString(AccountManager.KeyErrorMessage); if (!string.IsNullOrEmpty(msg)) { throw new AdalException(errCode.ToString(CultureInfo.InvariantCulture), msg); } else { bool initialRequest = bundleResult.ContainsKey(BrokerConstants.AccountInitialRequest); if (initialRequest) { // Initial request from app to Authenticator needs to launch // prompt. null resultEx means initial request return(null); } // IDtoken is not present in the current broker user model UserInfo userinfo = GetUserInfoFromBrokerResult(bundleResult); AuthenticationResult result = new AuthenticationResult("Bearer", bundleResult.GetString(AccountManager.KeyAuthtoken), ConvertFromTimeT(bundleResult.GetLong("account.expiredate", 0))) { UserInfo = userinfo }; result.UpdateTenantAndUserInfo(bundleResult.GetString(BrokerConstants.AccountUserInfoTenantId), null, userinfo); return(new AuthenticationResultEx { Result = result, RefreshToken = null, ResourceInResponse = null, }); } }
public static AuthenticationResult ParseTokenResponse(TokenResponse tokenResponse, CallState callState) { AuthenticationResult result; if (tokenResponse.AccessToken != null) { DateTimeOffset expiresOn = DateTime.UtcNow + TimeSpan.FromSeconds(tokenResponse.ExpiresIn); result = new AuthenticationResult(tokenResponse.TokenType, tokenResponse.AccessToken, tokenResponse.RefreshToken, expiresOn) { #if ADAL_NET // This is only needed for AcquireTokenByAuthorizationCode in which parameter resource is optional and we need // to get it from the STS response. Resource = tokenResponse.Resource, #endif }; IdToken idToken = ParseIdToken(tokenResponse.IdToken); if (idToken != null) { string tenantId = idToken.TenantId; string uniqueId = null; string displayableId = null; if (!string.IsNullOrWhiteSpace(idToken.ObjectId)) { uniqueId = idToken.ObjectId; } else if (!string.IsNullOrWhiteSpace(idToken.Subject)) { uniqueId = idToken.Subject; } if (!string.IsNullOrWhiteSpace(idToken.UPN)) { displayableId = idToken.UPN; } else if (!string.IsNullOrWhiteSpace(idToken.Email)) { displayableId = idToken.Email; } string givenName = idToken.GivenName; string familyName = idToken.FamilyName; string identityProvider = idToken.IdentityProvider ?? idToken.Issuer; DateTimeOffset? passwordExpiresOffest = null; if (idToken.PasswordExpiration > 0) { passwordExpiresOffest = DateTime.UtcNow + TimeSpan.FromSeconds(idToken.PasswordExpiration); } Uri changePasswordUri = null; if (!string.IsNullOrEmpty(idToken.PasswordChangeUrl)) { changePasswordUri = new Uri(idToken.PasswordChangeUrl); } result.UpdateTenantAndUserInfo(tenantId, tokenResponse.IdToken, new UserInfo { UniqueId = uniqueId, DisplayableId = displayableId, GivenName = givenName, FamilyName = familyName, IdentityProvider = identityProvider, PasswordExpiresOn = passwordExpiresOffest, PasswordChangeUrl = changePasswordUri }); } } else if (tokenResponse.Error != null) { throw new AdalServiceException(tokenResponse.Error, tokenResponse.ErrorDescription); } else { throw new AdalServiceException(AdalError.Unknown, AdalErrorMessage.Unknown); } return result; }
internal AuthenticationResult LoadFromCache(string authority, string resource, string clientId, TokenSubjectType subjectType, string uniqueId, string displayableId, CallState callState) { lock (cacheLock) { Logger.Verbose(callState, "Looking up cache for a token..."); AuthenticationResult result = null; KeyValuePair<TokenCacheKey, AuthenticationResult>? kvp = this.LoadSingleItemFromCache(authority, resource, clientId, subjectType, uniqueId, displayableId, callState); if (kvp.HasValue) { TokenCacheKey cacheKey = kvp.Value.Key; result = kvp.Value.Value; bool tokenNearExpiry = (result.ExpiresOn <= DateTime.UtcNow + TimeSpan.FromMinutes(ExpirationMarginInMinutes)); if (tokenNearExpiry) { result.AccessToken = null; Logger.Verbose(callState, "An expired or near expiry token was found in the cache"); } else if (!cacheKey.ResourceEquals(resource)) { Logger.Verbose(callState, string.Format( "Multi resource refresh token for resource '{0}' will be used to acquire token for '{1}'", cacheKey.Resource, resource)); var newResult = new AuthenticationResult(null, null, result.RefreshToken, DateTimeOffset.MinValue); newResult.UpdateTenantAndUserInfo(result.TenantId, result.IdToken, result.UserInfo); result = newResult; } else { Logger.Verbose(callState, string.Format("{0} minutes left until token in cache expires", (result.ExpiresOn - DateTime.UtcNow).TotalMinutes)); } if (result.AccessToken == null && result.RefreshToken == null) { this.tokenCacheDictionary.Remove(cacheKey); Logger.Information(callState, "An old item was removed from the cache"); this.HasStateChanged = true; result = null; } if (result != null) { Logger.Information(callState, "A matching item (access token or refresh token or both) was found in the cache"); } } else { Logger.Information(callState, "No matching token was found in the cache"); } return result; } }
public AuthenticationResultEx GetResult(DateTimeOffset expiresOn, DateTimeOffset extendedExpiresOn) { AuthenticationResultEx resultEx; if (this.AccessToken != null) { var result = new AuthenticationResult(this.TokenType, this.AccessToken, expiresOn, extendedExpiresOn); IdToken idToken = IdToken.Parse(this.IdTokenString); if (idToken != null) { string tenantId = idToken.TenantId; string uniqueId = null; string displayableId = null; if (!string.IsNullOrWhiteSpace(idToken.ObjectId)) { uniqueId = idToken.ObjectId; } else if (!string.IsNullOrWhiteSpace(idToken.Subject)) { uniqueId = idToken.Subject; } if (!string.IsNullOrWhiteSpace(idToken.UPN)) { displayableId = idToken.UPN; } else if (!string.IsNullOrWhiteSpace(idToken.Email)) { displayableId = idToken.Email; } string givenName = idToken.GivenName; string familyName = idToken.FamilyName; string identityProvider = idToken.IdentityProvider ?? idToken.Issuer; DateTimeOffset?passwordExpiresOffest = null; if (idToken.PasswordExpiration > 0) { passwordExpiresOffest = DateTime.UtcNow + TimeSpan.FromSeconds(idToken.PasswordExpiration); } Uri changePasswordUri = null; if (!string.IsNullOrEmpty(idToken.PasswordChangeUrl)) { changePasswordUri = new Uri(idToken.PasswordChangeUrl); } result.UpdateTenantAndUserInfo(tenantId, this.IdTokenString, new UserInfo { UniqueId = uniqueId, DisplayableId = displayableId, GivenName = givenName, FamilyName = familyName, IdentityProvider = identityProvider, PasswordExpiresOn = passwordExpiresOffest, PasswordChangeUrl = changePasswordUri }); result.Authority = Authority; } resultEx = new AuthenticationResultEx { Result = result, RefreshToken = this.RefreshToken, // This is only needed for AcquireTokenByAuthorizationCode in which parameter resource is optional and we need // to get it from the STS response. ResourceInResponse = this.Resource }; } else if (this.Error != null) { throw new AdalServiceException(this.Error, this.ErrorDescription); } else { throw new AdalServiceException(AdalError.Unknown, AdalErrorMessage.Unknown); } return(resultEx); }
public static AuthenticationResult ParseTokenResponse(TokenResponse tokenResponse, CallState callState) { AuthenticationResult result; if (tokenResponse.AccessToken != null) { DateTimeOffset expiresOn = DateTime.UtcNow + TimeSpan.FromSeconds(tokenResponse.ExpiresIn); result = new AuthenticationResult(tokenResponse.TokenType, tokenResponse.AccessToken, tokenResponse.RefreshToken, expiresOn) { // This is only needed for AcquireTokenByAuthorizationCode in which parameter resource is optional and we need // to get it from the STS response. Resource = tokenResponse.Resource, IsMultipleResourceRefreshToken = (!string.IsNullOrWhiteSpace(tokenResponse.RefreshToken) && !string.IsNullOrWhiteSpace(tokenResponse.Resource)), }; IdToken idToken = ParseIdToken(tokenResponse.IdToken); if (idToken != null) { string tenantId = idToken.TenantId; string uniqueId = null; string displayableId = null; if (!string.IsNullOrWhiteSpace(idToken.ObjectId)) { uniqueId = idToken.ObjectId; } else if (!string.IsNullOrWhiteSpace(idToken.Subject)) { uniqueId = idToken.Subject; } if (!string.IsNullOrWhiteSpace(idToken.UPN)) { displayableId = idToken.UPN; } else if (!string.IsNullOrWhiteSpace(idToken.Email)) { displayableId = idToken.Email; } string givenName = idToken.GivenName; string familyName = idToken.FamilyName; string identityProvider = idToken.IdentityProvider ?? idToken.Issuer; DateTimeOffset?passwordExpiresOffest = null; if (idToken.PasswordExpiration > 0) { passwordExpiresOffest = DateTime.UtcNow + TimeSpan.FromSeconds(idToken.PasswordExpiration); } Uri changePasswordUri = null; if (!string.IsNullOrEmpty(idToken.PasswordChangeUrl)) { changePasswordUri = new Uri(idToken.PasswordChangeUrl); } result.UpdateTenantAndUserInfo(tenantId, tokenResponse.IdToken, new UserInfo { UniqueId = uniqueId, DisplayableId = displayableId, GivenName = givenName, FamilyName = familyName, IdentityProvider = identityProvider, PasswordExpiresOn = passwordExpiresOffest, PasswordChangeUrl = changePasswordUri }); } } else if (tokenResponse.Error != null) { var ex = new AdalServiceException(tokenResponse.Error, tokenResponse.ErrorDescription); PlatformPlugin.Logger.LogException(callState, ex); throw ex; } else { var ex = new AdalServiceException(AdalError.Unknown, AdalErrorMessage.Unknown); PlatformPlugin.Logger.LogException(callState, ex); throw ex; } return(result); }
private AuthenticationResultEx GetResult(string token, string scope) { DateTimeOffset expiresOn = DateTime.UtcNow + TimeSpan.FromSeconds(this.ExpiresIn); var result = new AuthenticationResult(this.TokenType, token, expiresOn); ProfileInfo profileInfo = ProfileInfo.Parse(this.ProfileInfoString); if (profileInfo != null) { string tenantId = profileInfo.TenantId; string uniqueId = null; string displayableId = null; if (!string.IsNullOrWhiteSpace(profileInfo.ObjectId)) { uniqueId = profileInfo.ObjectId; } else if (!string.IsNullOrWhiteSpace(profileInfo.Subject)) { uniqueId = profileInfo.Subject; } if (!string.IsNullOrWhiteSpace(profileInfo.UPN)) { displayableId = profileInfo.UPN; } else if (!string.IsNullOrWhiteSpace(profileInfo.Email)) { displayableId = profileInfo.Email; } string givenName = profileInfo.GivenName; string familyName = profileInfo.FamilyName; string identityProvider = profileInfo.IdentityProvider ?? profileInfo.Issuer; DateTimeOffset? passwordExpiresOffest = null; if (profileInfo.PasswordExpiration > 0) { passwordExpiresOffest = DateTime.UtcNow + TimeSpan.FromSeconds(profileInfo.PasswordExpiration); } Uri changePasswordUri = null; if (!string.IsNullOrEmpty(profileInfo.PasswordChangeUrl)) { changePasswordUri = new Uri(profileInfo.PasswordChangeUrl); } result.UpdateTenantAndUserInfo(tenantId, this.ProfileInfoString, new UserInfo { UniqueId = uniqueId, DisplayableId = displayableId, GivenName = givenName, FamilyName = familyName, IdentityProvider = identityProvider, PasswordExpiresOn = passwordExpiresOffest, PasswordChangeUrl = changePasswordUri }); } return new AuthenticationResultEx { Result = result, RefreshToken = this.RefreshToken, // This is only needed for AcquireTokenByAuthorizationCode in which parameter resource is optional and we need // to get it from the STS response. ScopeInResponse = ADALScopeHelper.CreateArrayFromSingleString(scope) }; }