public void ConstructorInitCombinations() { //no policy, user properties TokenCacheKey key = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant, TestConstants.DefaultScope, TestConstants.DefaultClientId, TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId); this.ValidateTokenCacheKey(key, true); //with policy, user properties key = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant, TestConstants.DefaultScope, TestConstants.DefaultClientId, TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId, TestConstants.DefaultPolicy); this.ValidateTokenCacheKey(key, false); User user = new User(); user.DisplayableId = TestConstants.DefaultDisplayableId; user.UniqueId = TestConstants.DefaultUniqueId; user.HomeObjectId = TestConstants.DefaultHomeObjectId; //no policy, user object key = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant, TestConstants.DefaultScope, TestConstants.DefaultClientId, user); this.ValidateTokenCacheKey(key, true); //with policy, user object key = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant, TestConstants.DefaultScope, TestConstants.DefaultClientId, user, TestConstants.DefaultPolicy); this.ValidateTokenCacheKey(key, false); }
internal User(User other) { this.UniqueId = other.UniqueId; this.DisplayableId = other.DisplayableId; this.HomeObjectId = other.HomeObjectId; this.Name = other.Name; this.ClientId = other.ClientId; this.TokenCache = other.TokenCache; }
public static async Task<AuthenticationResult> GetTokenSilentAsync(User user) { TokenBroker brkr = new TokenBroker(); PublicClientApplication app = new PublicClientApplication("7c7a2f70-caef-45c8-9a6c-091633501de4"); try { return await app.AcquireTokenSilentAsync(brkr.Sts.ValidScope); } catch (Exception ex) { string msg = ex.Message + "\n" + ex.StackTrace; Console.WriteLine(msg); return await app.AcquireTokenAsync(brkr.Sts.ValidScope, user.DisplayableId, UiOptions.ActAsCurrentUser, null); } }
internal void UpdateTenantAndUser(string tenantId, string idToken, User otherUser) { this.TenantId = tenantId; this.IdToken = idToken; if (otherUser != null) { this.User = new User(otherUser); } }
internal async Task<AuthenticationResult> AcquireTokenSilentCommonAsync(Authenticator authenticator, string[] scope, User user, IPlatformParameters parameters, string policy, bool forceRefresh) { if (parameters == null) { parameters = PlatformPlugin.DefaultPlatformParameters; } var handler = new SilentRequest(this.GetHandlerData(authenticator, scope, policy, this.UserTokenCache), user, parameters, forceRefresh); return await handler.RunAsync().ConfigureAwait(false); }
/// <summary> /// /// </summary> /// <param name="scope"></param> /// <param name="user"></param> /// <param name="authority"></param> /// <param name="policy"></param> /// <param name="forceRefresh"></param> /// <returns></returns> public async Task<AuthenticationResult> AcquireTokenSilentAsync(string[] scope, User user, string authority, string policy, bool forceRefresh) { Authenticator authenticator = new Authenticator(authority, this.ValidateAuthority, this.CorrelationId); return await this.AcquireTokenSilentCommonAsync(authenticator, scope, user, this.PlatformParameters, policy, forceRefresh).ConfigureAwait(false); }
private async Task<AuthenticationResult> AcquireTokenCommonAsync(Authenticator authenticator, string[] scope, string[] additionalScope, Uri redirectUri, User user, UiOptions uiOptions, string extraQueryParameters, string policy) { if (this.PlatformParameters == null) { this.PlatformParameters = PlatformPlugin.DefaultPlatformParameters; } var handler = new InteractiveRequest( this.GetHandlerData(authenticator, scope, policy, this.UserTokenCache), additionalScope, redirectUri, this.PlatformParameters, user, uiOptions, extraQueryParameters, this.CreateWebAuthenticationDialog(this.PlatformParameters)); return await handler.RunAsync().ConfigureAwait(false); }
/// <summary> /// /// </summary> /// <param name="scope"></param> /// <param name="user"></param> /// <param name="options"></param> /// <param name="extraQueryParameters"></param> /// <param name="additionalScope"></param> /// <param name="authority"></param> /// <param name="policy"></param> /// <returns></returns> public async Task<AuthenticationResult> AcquireTokenAsync(string[] scope, User user, UiOptions options, string extraQueryParameters, string[] additionalScope, string authority, string policy) { Authenticator authenticator = new Authenticator(authority, this.ValidateAuthority, this.CorrelationId); return await this.AcquireTokenCommonAsync(authenticator, scope, additionalScope, new Uri(this.RedirectUri), user, options, extraQueryParameters, policy).ConfigureAwait(false); }
private List<KeyValuePair<TokenCacheKey, AuthenticationResultEx>> QueryCache(string authority, string clientId, User user, string policy) { return this.QueryCache( authority, clientId, user?.UniqueId, user?.DisplayableId, user?.HomeObjectId, policy); }
internal KeyValuePair<TokenCacheKey, AuthenticationResultEx>? LoadSingleItemFromCache(string authority, HashSet<string> scope, string clientId, User user, string policy, CallState callState) { lock (lockObject) { string uniqueId = null; string displayableId = null; string rootId = null; if (user != null) { uniqueId = user.UniqueId; displayableId = user.DisplayableId; rootId = user.HomeObjectId; } if (uniqueId == null && displayableId == null && rootId == null) { PlatformPlugin.Logger.Information(null, "No user information provided."); // if authority is common and there are multiple unique ids in the cache // then throw MultipleTokensMatched because code cannot guess which user // is requested by the developer. if (Authenticator.IsTenantLess(authority) && this.GetUniqueIdsFromCache(clientId).Count() > 1) { throw new MsalException(MsalError.MultipleTokensMatched); } } if (Authenticator.IsTenantLess(authority)) { authority = null; //ignore authority } // First identify all potential tokens. List<KeyValuePair<TokenCacheKey, AuthenticationResultEx>> items = this.QueryCache(authority, clientId, uniqueId, displayableId, rootId, policy); //using ScopeContains because user could be accessing a subset of the scope. List<KeyValuePair<TokenCacheKey, AuthenticationResultEx>> scopeSpecificItems = items.Where(p => p.Key.ScopeContains(scope)).ToList(); int scopeValuesCount = scopeSpecificItems.Count(); KeyValuePair<TokenCacheKey, AuthenticationResultEx>? returnValue = null; switch (scopeValuesCount) { case 1: PlatformPlugin.Logger.Information(callState, "An item matching the requested scope set was found in the cache"); returnValue = scopeSpecificItems.First(); break; case 0: { //look for intersecting scope first scopeSpecificItems = items.Where(p => p.Key.ScopeIntersects(scope)).ToList(); if (!scopeSpecificItems.Any()) { //Choose any of the MRRT tokens if there are any. scopeSpecificItems = items.Where(p => p.Value.IsMultipleScopeRefreshToken).ToList(); if (scopeSpecificItems.Any()) { returnValue = scopeSpecificItems.First(); PlatformPlugin.Logger.Information(callState, "A Multi Scope Refresh Token for a different scope was found which can be used"); } } else { returnValue = scopeSpecificItems.First(); //return intersecting scopes } } break; default: throw new MsalException(MsalError.MultipleTokensMatched); } if (user != null) { // check for tokens issued to same client_id/user_id combination, but any tenant. // cross tenant should not be used when there is no user provided, unless we are running in // RestrictToSingleUser mode. if (returnValue == null) { List<KeyValuePair<TokenCacheKey, AuthenticationResultEx>> itemsForAllTenants = this.QueryCache( null, clientId, null, null, rootId, policy); if (itemsForAllTenants.Count > 0) { returnValue = itemsForAllTenants.First(); } } // look for family of client id if (returnValue == null) { // set authority and client id to null. List<KeyValuePair<TokenCacheKey, AuthenticationResultEx>> itemsForFamily = this.QueryCache(null, null, null, null, rootId, policy) .Where(kvp => kvp.Value.Result != null && kvp.Value.Result.FamilyId != null).ToList(); if (itemsForFamily.Count > 0) { returnValue = itemsForFamily.First(); } } } return returnValue; } }
internal virtual AuthenticationResultEx LoadFromCache(string authority, HashSet<string> scope, string clientId, User user, string policy, CallState callState) { lock (lockObject) { PlatformPlugin.Logger.Verbose(callState, "Looking up cache for a token..."); AuthenticationResultEx resultEx = null; //get either a matching token or an MRRT supported RT KeyValuePair<TokenCacheKey, AuthenticationResultEx>? kvp = this.LoadSingleItemFromCache(authority, scope, clientId, user, policy, callState); TokenCacheKey cacheKey = null; if (kvp.HasValue) { cacheKey = kvp.Value.Key; resultEx = kvp.Value.Value; bool tokenNearExpiry = (resultEx.Result.ExpiresOn <= DateTime.UtcNow + TimeSpan.FromMinutes(Constant.ExpirationMarginInMinutes)); if (!cacheKey.ScopeContains(scope) || (!Authenticator.IsTenantLess(authority) && !authority.Equals(cacheKey.Authority)) || !clientId.Equals(cacheKey.ClientId)) { //requested scope are not a subset or authority does not match (cross-tenant RT) or client id is not same (FoCI). PlatformPlugin.Logger.Verbose(callState, string.Format(CultureInfo.InvariantCulture,"Refresh token for scope '{0}' will be used to acquire token for '{1}'", cacheKey.Scope.AsSingleString(), scope.AsSingleString())); resultEx = CreateResultExFromCacheResultEx(cacheKey, resultEx); } else if (tokenNearExpiry) { resultEx.Result.Token = null; PlatformPlugin.Logger.Verbose(callState, "An expired or near expiry token was found in the cache"); } else { PlatformPlugin.Logger.Verbose(callState, string.Format(CultureInfo.InvariantCulture,"{0} minutes left until token in cache expires", (resultEx.Result.ExpiresOn - DateTime.UtcNow).TotalMinutes)); } // client credential tokens do not have associated refresh tokens. if (resultEx.Result.Token == null && resultEx.RefreshToken == null) { this.tokenCacheDictionary.Remove(cacheKey); PlatformPlugin.Logger.Information(callState, "An old item was removed from the cache"); this.HasStateChanged = true; resultEx = null; } if (resultEx != null) { PlatformPlugin.Logger.Information(callState, "A matching item (access token or refresh token or both) was found in the cache"); } } return resultEx; } }