internal static void TokenCacheSerializationTest()
        {
            var       context      = new AuthenticationContext("https://login.windows.net/common", false);
            var       tokenCache   = context.TokenCache;
            const int MaxItemCount = 100;
            const int MaxFieldSize = 1024;

            tokenCache.Clear();
            for (int count = 0; count < Rand.Next(1, MaxItemCount); count++)
            {
                TokenCacheKey          key    = GenerateRandomTokenCacheKey();
                AuthenticationResultEx result = GenerateRandomCacheValue(MaxFieldSize, key.UniqueId, key.DisplayableId);
                AddToDictionary(tokenCache, key, result);
            }

            byte[]     serializedCache = tokenCache.Serialize();
            TokenCache tokenCache2     = new TokenCache(serializedCache);

            Assert.AreEqual(tokenCache.Count, tokenCache2.Count);
            foreach (TokenCacheItem item in tokenCache.ReadItems())
            {
                var item2 = tokenCache2.ReadItems().FirstOrDefault(it => it.AccessToken == item.AccessToken);
                Assert.IsNotNull(item2);
                double diff = Math.Abs((item.ExpiresOn - item2.ExpiresOn).TotalSeconds);
                Assert.IsTrue((1.0 - diff) >= 0);
            }

            foreach (var key in tokenCache.tokenCacheDictionary.Keys)
            {
                AuthenticationResultEx result2 = tokenCache2.tokenCacheDictionary[key];
                VerifyAuthenticationResultExsAreEqual(tokenCache.tokenCacheDictionary[key], result2);
            }
        }
        internal static void SetBrokerResult(Intent data, int resultCode)
        {
            if (resultCode != BrokerResponseCode.ResponseReceived)
            {
                resultEx = new AuthenticationResultEx
                {
                    Exception =
                        new AdalException(data.GetStringExtra(BrokerConstants.ResponseErrorCode),
                                          data.GetStringExtra(BrokerConstants.ResponseErrorMessage))
                };
            }
            else
            {
                var tokenResponse = new TokenResponse
                {
                    Authority     = data.GetStringExtra(BrokerConstants.AccountAuthority),
                    AccessToken   = data.GetStringExtra(BrokerConstants.AccountAccessToken),
                    IdTokenString = data.GetStringExtra(BrokerConstants.AccountIdToken),
                    TokenType     = "Bearer",
                    ExpiresOn     = data.GetLongExtra(BrokerConstants.AccountExpireDate, 0)
                };

                resultEx = tokenResponse.GetResult(BrokerProxy.ConvertFromTimeT(tokenResponse.ExpiresOn),
                                                   BrokerProxy.ConvertFromTimeT(tokenResponse.ExpiresOn));
            }

            readyForResponse.Release();
        }
        internal static void TokenCacheCapacityTest()
        {
            var tokenCache = new TokenCache();

            tokenCache.Clear();

            const int MaxItemCount = 100;

            TokenCacheKey[]          keys   = new TokenCacheKey[MaxItemCount];
            AuthenticationResultEx[] values = new AuthenticationResultEx[MaxItemCount];

            for (int i = 0; i < MaxItemCount; i++)
            {
                keys[i] = GenerateRandomTokenCacheKey();

                values[i] = CreateCacheValue(null, null);
                AddToDictionary(tokenCache, keys[i], values[i]);
            }

            Assert.AreEqual(MaxItemCount, tokenCache.Count);

            for (int i = 0; i < MaxItemCount; i++)
            {
                AuthenticationResultEx cacheValue;
                int index = MaxItemCount - i - 1;
                Assert.IsTrue(tokenCache.tokenCacheDictionary.TryGetValue(keys[index], out cacheValue));
                Assert.AreEqual(values[index], cacheValue);
                RemoveFromDictionary(tokenCache, keys[index]);
                Assert.AreEqual(index, tokenCache.Count);
            }

            tokenCache.Clear();
        }
        protected override async Task <AuthenticationResultEx> SendTokenRequestAsync()
        {
            TimeSpan timeRemaining          = deviceCodeResult.ExpiresOn - DateTimeOffset.UtcNow;
            AuthenticationResultEx resultEx = null;

            //the interval is added so that the while loop does not end before aquiring the last response from the STS stating that the code has expired.
            //Without it, resultEx will end up being null.
            while (timeRemaining.TotalSeconds + deviceCodeResult.Interval > 0)
            {
                try
                {
                    resultEx = await base.SendTokenRequestAsync().ConfigureAwait(false);

                    break;
                }
                catch (AdalServiceException exc)
                {
                    if (!exc.ErrorCode.Equals(AdalErrorEx.DeviceCodeAuthorizationPendingError))
                    {
                        throw;
                    }
                }

                await Task.Delay(TimeSpan.FromSeconds(deviceCodeResult.Interval)).ConfigureAwait(false);

                timeRemaining = deviceCodeResult.ExpiresOn - DateTimeOffset.UtcNow;
            }

            return(resultEx);
        }
 private static bool AreAuthenticationResultExsEqual(AuthenticationResultEx resultEx1,
                                                     AuthenticationResultEx resultEx2)
 {
     return(AreAuthenticationResultsEqual(resultEx1.Result, resultEx2.Result) &&
            resultEx1.RefreshToken == resultEx2.RefreshToken &&
            resultEx1.IsMultipleResourceRefreshToken == resultEx2.IsMultipleResourceRefreshToken &&
            resultEx1.UserAssertionHash == resultEx2.UserAssertionHash);
 }
        public void IdTokenParsingNoPasswordClaimsTest()
        {
            TokenResponse tr = CreateTokenResponse();

            tr.IdTokenString = "eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJhdWQiOiI5MDgzY2NiOC04YTQ2LTQzZTctODQzOS0xZDY5NmRmOTg0YWUiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC8zMGJhYTY2Ni04ZGY4LTQ4ZTctOTdlNi03N2NmZDA5OTU5NjMvIiwiaWF0IjoxNDAwNTQxMzk1LCJuYmYiOjE0MDA1NDEzOTUsImV4cCI6MTQwMDU0NTU5NSwidmVyIjoiMS4wIiwidGlkIjoiMzBiYWE2NjYtOGRmOC00OGU3LTk3ZTYtNzdjZmQwOTk1OTYzIiwib2lkIjoiNGY4NTk5ODktYTJmZi00MTFlLTkwNDgtYzMyMjI0N2FjNjJjIiwidXBuIjoiYWRtaW5AYWFsdGVzdHMub25taWNyb3NvZnQuY29tIiwidW5pcXVlX25hbWUiOiJhZG1pbkBhYWx0ZXN0cy5vbm1pY3Jvc29mdC5jb20iLCJzdWIiOiJCczVxVG4xQ3YtNC10VXIxTGxBb3pOS1NRd0Fjbm4ydHcyQjlmelduNlpJIiwiZmFtaWx5X25hbWUiOiJBZG1pbiIsImdpdmVuX25hbWUiOiJBREFMVGVzdHMifQ.";
            AuthenticationResultEx result = tr.GetResult();

            Assert.IsNull(result.Result.UserInfo.PasswordChangeUrl);
            Assert.IsNull(result.Result.UserInfo.PasswordExpiresOn);
        }
Example #7
0
        protected override async Task <AuthenticationResultEx> SendTokenRequestAsync()
        {
            AuthenticationResultEx resultEx = await base.SendTokenRequestAsync().ConfigureAwait(false);

            if (resultEx != null)
            {
                resultEx.UserAssertionHash = CacheQueryData.AssertionHash;
            }

            return(resultEx);
        }
Example #8
0
        internal void StoreToCache(AuthenticationResultEx resultEx, string authority, string clientId,
                                   string policy, bool restrictToSingleUser, CallState callState)
        {
            lock (lockObject)
            {
                PlatformPlugin.Logger.Verbose(callState, "Storing token in the cache...");

                //single user mode cannot allow more than 1 unique id in the cache including null
                if (restrictToSingleUser &&
                    (resultEx.Result.User == null || string.IsNullOrEmpty(resultEx.Result.User.UniqueId) ||
                     !this.GetUniqueIdsFromCache(clientId).Contains(resultEx.Result.User.UniqueId)))
                {
                    throw new MsalException(MsalError.InvalidCacheOperation,
                                            "Cannot add more than 1 user with a different unique id when RestrictToSingleUser is set to TRUE.");
                }

                this.OnBeforeWrite(new TokenCacheNotificationArgs
                {
                    Scope    = resultEx.Result.Scope,
                    ClientId = clientId,
                    User     = resultEx.Result.User,
                    Policy   = policy
                });

                TokenCacheKey tokenCacheKey = new TokenCacheKey(authority, resultEx.Result.ScopeSet, clientId,
                                                                resultEx.Result.User, policy);
                // First identify all potential tokens.
                List <KeyValuePair <TokenCacheKey, AuthenticationResultEx> > items = this.QueryCache(authority, clientId,
                                                                                                     resultEx.Result.User, policy);
                List <KeyValuePair <TokenCacheKey, AuthenticationResultEx> > itemsToRemove =
                    items.Where(p => p.Key.ScopeIntersects(resultEx.Result.ScopeSet)).ToList();

                if (!itemsToRemove.Any())
                {
                    this.tokenCacheDictionary[tokenCacheKey] = resultEx;
                    PlatformPlugin.Logger.Verbose(callState, "An item was stored in the cache");
                }
                else
                {
                    //remove all intersections
                    PlatformPlugin.Logger.Verbose(callState, "Items to remove - " + itemsToRemove.Count);
                    foreach (var itemToRemove in itemsToRemove)
                    {
                        this.tokenCacheDictionary.Remove(itemToRemove);
                    }

                    this.tokenCacheDictionary[tokenCacheKey] = resultEx;
                    PlatformPlugin.Logger.Verbose(callState, "An item was updated in the cache");
                }

                this.UpdateCachedRefreshTokens(resultEx, authority, clientId, policy);
                this.HasStateChanged = true;
            }
        }
Example #9
0
        protected override async Task <AuthenticationResultEx> SendTokenRequestAsync()
        {
            AuthenticationResultEx resultEx = await base.SendTokenRequestAsync();

            if (resultEx != null)
            {
                resultEx.UserAssertionHash = this.assertionHash;
            }

            return(resultEx);
        }
        internal static void TokenCacheCrossTenantOperationsTest()
        {
            var tokenCache      = new TokenCache();
            var cacheDictionary = tokenCache.tokenCacheDictionary;

            tokenCache.Clear();

            TokenCacheKey key = new TokenCacheKey("https://localhost/MockSts/", "resource1", "client1",
                                                  TokenSubjectType.User, null, "user1");
            AuthenticationResultEx value = CreateCacheValue(null, "user1");
        }
Example #11
0
        protected virtual async Task PostTokenRequest(AuthenticationResultEx resultEx)
        {
            // if broker returned Authority update Authentiator
            if (!string.IsNullOrEmpty(resultEx.Result.Authority))
            {
                await UpdateAuthority(resultEx.Result.Authority).ConfigureAwait(false);
            }

            this.Authenticator.UpdateTenantId(resultEx.Result.TenantId);

            resultEx.Result.Authority = Authenticator.Authority;
        }
        internal User MapIdentifierToUser(string identifier)
        {
            string displayableId = null;
            string uniqueId      = null;

            if (!string.IsNullOrEmpty(identifier))
            {
                if (identifier.Contains("@"))
                {
                    displayableId = identifier;
                }
                else
                {
                    uniqueId = identifier;
                }
            }

            if (this.tokenCache != null)
            {
                bool notifiedBeforeAccessCache = false;
                try
                {
                    User user = new User()
                    {
                        UniqueId      = uniqueId,
                        DisplayableId = displayableId
                    };

                    this.NotifyBeforeAccessCache();
                    notifiedBeforeAccessCache = true;

                    AuthenticationResultEx resultEx = this.tokenCache.LoadFromCache(this.Authenticator.Authority,
                                                                                    this.Scope,
                                                                                    this.ClientKey.ClientId, user,
                                                                                    this.Policy, this.CallState);
                    if (resultEx != null)
                    {
                        return(resultEx.Result.User);
                    }
                }
                finally
                {
                    if (notifiedBeforeAccessCache)
                    {
                        this.NotifyAfterAccessCache();
                    }
                }
            }

            return(null);
        }
        internal static void MultipleUserAssertionHashTest()
        {
            TokenCacheKey key = new TokenCacheKey("https://localhost/MockSts/", "resource1", "client1",
                                                  TokenSubjectType.Client, null, "user1");
            TokenCacheKey key2 = new TokenCacheKey("https://localhost/MockSts/", "resource1", "client1",
                                                   TokenSubjectType.Client, null, "user2");
            AuthenticationResultEx value = CreateCacheValue(null, "user1");

            value.UserAssertionHash = "hash1";
            AuthenticationResultEx value2 = CreateCacheValue(null, "user2");

            value2.UserAssertionHash = "hash2";

            TokenCache cache = new TokenCache();

            cache.tokenCacheDictionary[key]  = value;
            cache.tokenCacheDictionary[key2] = value2;
            CacheQueryData data = new CacheQueryData()
            {
                AssertionHash = "hash1",
                Authority     = "https://localhost/MockSts/",
                Resource      = "resource1",
                ClientId      = "client1",
                SubjectType   = TokenSubjectType.Client,
                UniqueId      = null,
                DisplayableId = null
            };

            AuthenticationResultEx resultEx = cache.LoadFromCache(data, null);

            AreAuthenticationResultExsEqual(value, resultEx);

            data.AssertionHash = "hash2";
            resultEx           = cache.LoadFromCache(data, null);
            AreAuthenticationResultExsEqual(value2, resultEx);

            data.AssertionHash = null;

            try
            {
                cache.LoadFromCache(data, null);
                Assert.Fail("multiple_tokens_detected should have been thrown");
            }
            catch (Exception exc)
            {
                Assert.IsTrue(exc is AdalException);
                Assert.AreEqual(((AdalException)exc).ErrorCode, AdalError.MultipleTokensMatched);
            }
        }
        public void GetUsersTest()
        {
            PublicClientApplication app   = new PublicClientApplication(TestConstants.DefaultClientId);
            IEnumerable <User>      users = app.Users;

            Assert.IsNotNull(users);
            Assert.IsFalse(users.Any());
            app.UserTokenCache = TokenCacheHelper.CreateCacheWithItems();
            users = app.Users;
            Assert.IsNotNull(users);
            Assert.AreEqual(1, users.Count());
            foreach (var user in users)
            {
                Assert.AreEqual(TestConstants.DefaultClientId, user.ClientId);
                Assert.IsNotNull(user.TokenCache);
            }

            // another cache entry for different home object id. user count should be 2.
            TokenCacheKey key = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                                                  TestConstants.ScopeForAnotherResource, TestConstants.DefaultClientId,
                                                  TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId + "more",
                                                  TestConstants.DefaultPolicy);
            AuthenticationResultEx ex = new AuthenticationResultEx();

            ex.Result = new AuthenticationResult("Bearer", key.ToString(),
                                                 new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(3600)));
            ex.Result.User = new User
            {
                DisplayableId = TestConstants.DefaultDisplayableId,
                UniqueId      = TestConstants.DefaultUniqueId,
                HomeObjectId  = TestConstants.DefaultHomeObjectId
            };
            ex.Result.ScopeSet = TestConstants.DefaultScope;

            ex.Result.FamilyId = "1";
            ex.RefreshToken    = "someRT";
            app.UserTokenCache.tokenCacheDictionary[key] = ex;

            users = app.Users;
            Assert.IsNotNull(users);
            Assert.AreEqual(2, users.Count());
            foreach (var user in users)
            {
                Assert.AreEqual(TestConstants.DefaultClientId, user.ClientId);
                Assert.IsNotNull(user.TokenCache);
            }
        }
Example #15
0
        /// <summary>
        ///     Deserializes state of the cache. The state should be the blob received earlier by calling the method Serialize.
        /// </summary>
        /// <param name="state">State of the cache as a blob</param>
        public void Deserialize(byte[] state)
        {
            lock (lockObject)
            {
                if (state == null || state.Length == 0)
                {
                    this.tokenCacheDictionary.Clear();
                    return;
                }

                using (Stream stream = new MemoryStream())
                {
                    BinaryWriter writer = new BinaryWriter(stream);
                    writer.Write(state);
                    writer.Flush();
                    stream.Position = 0;

                    BinaryReader reader        = new BinaryReader(stream);
                    int          schemaVersion = reader.ReadInt32();
                    if (schemaVersion != SchemaVersion)
                    {
                        PlatformPlugin.Logger.Warning(null,
                                                      "The version of the persistent state of the cache does not match the current schema, so skipping deserialization.");
                        return;
                    }

                    this.tokenCacheDictionary.Clear();
                    int count = reader.ReadInt32();
                    for (int n = 0; n < count; n++)
                    {
                        string keyString = reader.ReadString();

                        string[] kvpElements            = keyString.Split(new[] { Delimiter }, StringSplitOptions.None);
                        AuthenticationResultEx resultEx = AuthenticationResultEx.Deserialize(reader.ReadString());

                        TokenCacheKey key = new TokenCacheKey(kvpElements[0],
                                                              kvpElements[1].AsSet(), kvpElements[2], resultEx.Result.User, kvpElements[3]);

                        this.tokenCacheDictionary.Add(key, resultEx);
                    }

                    PlatformPlugin.Logger.Information(null,
                                                      string.Format(CultureInfo.InvariantCulture, "Deserialized {0} items to token cache.", count));
                }
            }
        }
        internal async Task <AuthenticationResultEx> SendTokenRequestByRefreshTokenAsync(string refreshToken)
        {
            var requestParameters = new DictionaryRequestParameters(this.GetDecoratedScope(this.Scope), this.ClientKey);

            requestParameters[OAuthParameter.GrantType]    = OAuthGrantType.RefreshToken;
            requestParameters[OAuthParameter.RefreshToken] = refreshToken;

            AuthenticationResultEx result = await this.SendHttpMessageAsync(requestParameters).ConfigureAwait(false);

            if (result.RefreshToken == null)
            {
                result.RefreshToken = refreshToken;
                PlatformPlugin.Logger.Information(this.CallState, "Refresh token was missing from the token refresh response, so the refresh token in the request is returned instead");
            }

            return(result);
        }
        public void ActAsCurrentUserNoSsoHeaderForLoginHintOnlyTest()
        {
            //this test validates that no SSO header is added when developer passes only login hint and UiOption.ActAsCurrentUser
            Authenticator authenticator = new Authenticator(TestConstants.DefaultAuthorityHomeTenant, false, Guid.NewGuid());
            TokenCache    cache         = new TokenCache();
            TokenCacheKey key           = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                                                            TestConstants.DefaultScope, TestConstants.DefaultClientId,
                                                            TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId,
                                                            TestConstants.DefaultPolicy);
            AuthenticationResultEx ex = new AuthenticationResultEx();

            ex.Result = new AuthenticationResult("Bearer", key.ToString(),
                                                 new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(3599)));
            ex.Result.User = new User
            {
                DisplayableId = TestConstants.DefaultDisplayableId,
                UniqueId      = TestConstants.DefaultUniqueId,
                HomeObjectId  = TestConstants.DefaultHomeObjectId
            };
            ex.Result.FamilyId = "1";
            ex.RefreshToken    = "someRT";
            cache.tokenCacheDictionary[key] = ex;

            MockWebUI webUi = new MockWebUI();

            webUi.MockResult = new AuthorizationResult(AuthorizationStatus.Success,
                                                       TestConstants.DefaultAuthorityHomeTenant + "?code=some-code");

            AuthenticationRequestParameters parameters = new AuthenticationRequestParameters()
            {
                Authenticator        = authenticator,
                ClientKey            = new ClientKey(TestConstants.DefaultClientId),
                Policy               = TestConstants.DefaultPolicy,
                RestrictToSingleUser = TestConstants.DefaultRestrictToSingleUser,
                Scope      = TestConstants.DefaultScope.ToArray(),
                TokenCache = cache
            };

            InteractiveRequest request = new InteractiveRequest(parameters,
                                                                TestConstants.ScopeForAnotherResource.ToArray(),
                                                                new Uri("some://uri"), new PlatformParameters(),
                                                                ex.Result.User, UiOptions.ActAsCurrentUser, "extra=qp", webUi);

            request.PreRunAsync().Wait();
            request.PreTokenRequest().Wait();
        }
Example #18
0
        private async Task <AuthenticationResultEx> RefreshAccessTokenAsync(AuthenticationResultEx result)
        {
            AuthenticationResultEx newResultEx = null;

            if (this.Resource != null)
            {
                var msg = "Refreshing access token...";
                CallState.Logger.Verbose(this.CallState, msg);
                CallState.Logger.VerbosePii(this.CallState, msg);

                try
                {
                    newResultEx = await this.SendTokenRequestByRefreshTokenAsync(result.RefreshToken)
                                  .ConfigureAwait(false);

                    this.Authenticator.UpdateTenantId(result.Result.TenantId);

                    newResultEx.Result.Authority = Authenticator.Authority;

                    if (newResultEx.Result.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.
                        newResultEx.Result.UpdateTenantAndUserInfo(result.Result.TenantId, result.Result.IdToken,
                                                                   result.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,
                                  serviceException.ServiceErrorCodes,
                                  serviceException);
                    }
                    newResultEx = new AuthenticationResultEx {
                        Exception = ex
                    };
                }
            }

            return(newResultEx);
        }
        internal static async Task MultipleUserAssertionHashTestAsync()
        {
            TokenCacheKey key = new TokenCacheKey("https://localhost/MockSts/", "resource1", "client1",
                                                  TokenSubjectType.Client, null, "user1");
            TokenCacheKey key2 = new TokenCacheKey("https://localhost/MockSts/", "resource1", "client1",
                                                   TokenSubjectType.Client, null, "user2");
            AuthenticationResultEx value = CreateCacheValue(null, "user1");

            value.UserAssertionHash = "hash1";
            AuthenticationResultEx value2 = CreateCacheValue(null, "user2");

            value2.UserAssertionHash = "hash2";

            TokenCache cache = new TokenCache();

            cache.tokenCacheDictionary[key]  = value;
            cache.tokenCacheDictionary[key2] = value2;
            CacheQueryData data = new CacheQueryData()
            {
                AssertionHash = "hash1",
                Authority     = "https://localhost/MockSts/",
                Resource      = "resource1",
                ClientId      = "client1",
                SubjectType   = TokenSubjectType.Client,
                UniqueId      = null,
                DisplayableId = null
            };

            AuthenticationResultEx resultEx = await cache.LoadFromCacheAsync(data, CallState.Default).ConfigureAwait(false);

            AreAuthenticationResultExsEqual(value, resultEx);

            data.AssertionHash = "hash2";
            resultEx           = await cache.LoadFromCacheAsync(data, CallState.Default).ConfigureAwait(false);

            AreAuthenticationResultExsEqual(value2, resultEx);

            data.AssertionHash = null;

            // Multiple tokens in cache -> error
            var exc = AssertException.TaskThrows <AdalException>(async() =>
                                                                 await cache.LoadFromCacheAsync(data, CallState.Default).ConfigureAwait(false));

            Assert.AreEqual(exc.ErrorCode, AdalError.MultipleTokensMatched);
        }
Example #20
0
        public void MapToIdentifierMultipleMatchingEntriesTest()
        {
            Authenticator authenticator = new Authenticator(TestConstants.DefaultAuthorityHomeTenant, false,
                                                            Guid.NewGuid());
            TokenCache cache = TokenCacheHelper.CreateCacheWithItems();

            TokenCacheKey key = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                                                  TestConstants.ScopeForAnotherResource, TestConstants.DefaultClientId,
                                                  TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId,
                                                  TestConstants.DefaultPolicy);
            AuthenticationResultEx ex = new AuthenticationResultEx();

            ex.Result = new AuthenticationResult("Bearer", key.ToString(),
                                                 new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(3600)));
            ex.Result.User = new User
            {
                DisplayableId = TestConstants.DefaultDisplayableId,
                UniqueId      = TestConstants.DefaultUniqueId,
                HomeObjectId  = TestConstants.DefaultHomeObjectId
            };
            ex.Result.ScopeSet = TestConstants.DefaultScope;

            ex.Result.FamilyId = "1";
            ex.RefreshToken    = "someRT";
            cache.tokenCacheDictionary[key] = ex;


            HandlerData data = new HandlerData()
            {
                Authenticator        = authenticator,
                ClientKey            = new ClientKey(TestConstants.DefaultClientId),
                Policy               = TestConstants.DefaultPolicy,
                RestrictToSingleUser = TestConstants.DefaultRestrictToSingleUser,
                Scope      = new[] { "something" },
                TokenCache = cache
            };

            AcquireTokenSilentHandler handler = new AcquireTokenSilentHandler(data, (string)null,
                                                                              new PlatformParameters(), false);
            User user = handler.MapIdentifierToUser(TestConstants.DefaultUniqueId);

            Assert.IsNotNull(user);
            Assert.AreEqual(TestConstants.DefaultUniqueId, user.UniqueId);
        }
Example #21
0
        private void UpdateCachedRefreshTokens(AuthenticationResultEx result, string authority, string clientId, string policy)
        {
            lock (lockObject)
            {
                if (result.Result.User != null && result.IsMultipleScopeRefreshToken)
                {
                    List <KeyValuePair <TokenCacheKey, AuthenticationResultEx> > mrrtItems =
                        this.QueryCache(authority, clientId, result.Result.User.UniqueId,
                                        result.Result.User.DisplayableId, result.Result.User.HomeObjectId, policy)
                        .Where(p => p.Value.IsMultipleScopeRefreshToken)
                        .ToList();

                    foreach (KeyValuePair <TokenCacheKey, AuthenticationResultEx> mrrtItem in mrrtItems)
                    {
                        mrrtItem.Value.RefreshToken = result.RefreshToken;
                    }
                }
            }
        }
Example #22
0
        public static TokenCache CreateCacheWithItems()
        {
            TokenCache    cache = new TokenCache();
            TokenCacheKey key   = new TokenCacheKey(TestConstants.DefaultAuthorityHomeTenant,
                                                    TestConstants.DefaultScope, TestConstants.DefaultClientId,
                                                    TestConstants.DefaultUniqueId, TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId,
                                                    TestConstants.DefaultPolicy);
            AuthenticationResultEx ex = new AuthenticationResultEx();

            ex.Result = new AuthenticationResult("Bearer", key.ToString(),
                                                 new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(ValidExpiresIn)));
            ex.Result.User = new User
            {
                DisplayableId = TestConstants.DefaultDisplayableId,
                UniqueId      = TestConstants.DefaultUniqueId,
                HomeObjectId  = TestConstants.DefaultHomeObjectId
            };
            ex.Result.ScopeSet = TestConstants.DefaultScope;

            ex.Result.FamilyId = "1";
            ex.RefreshToken    = "someRT";
            cache.tokenCacheDictionary[key] = ex;

            key = new TokenCacheKey(TestConstants.DefaultAuthorityGuestTenant,
                                    TestConstants.ScopeForAnotherResource, TestConstants.DefaultClientId,
                                    TestConstants.DefaultUniqueId + "more", TestConstants.DefaultDisplayableId, TestConstants.DefaultHomeObjectId,
                                    TestConstants.DefaultPolicy);
            ex        = new AuthenticationResultEx();
            ex.Result = new AuthenticationResult("Bearer", key.ToString(),
                                                 new DateTimeOffset(DateTime.UtcNow + TimeSpan.FromSeconds(ValidExpiresIn)));
            ex.Result.User = new User
            {
                DisplayableId = TestConstants.DefaultDisplayableId,
                UniqueId      = TestConstants.DefaultUniqueId + "more",
                HomeObjectId  = TestConstants.DefaultHomeObjectId
            };
            ex.Result.ScopeSet = TestConstants.ScopeForAnotherResource;
            ex.RefreshToken    = "someRT";
            cache.tokenCacheDictionary[key] = ex;

            return(cache);
        }
        public async Task <AuthenticationResultEx> AcquireTokenUsingBrokerAsync(IDictionary <string, string> brokerPayload)
        {
            mBrokerProxy.CallState = CallState;

            resultEx         = null;
            readyForResponse = new SemaphoreSlim(0);
            try
            {
                await Task.Run(() => AcquireToken(brokerPayload)).ConfigureAwait(false);
            }
            catch (Exception ex)
            {
                CallState.Logger.Error(null, ex);
                CallState.Logger.ErrorPii(null, ex);
                throw;
            }
            await readyForResponse.WaitAsync().ConfigureAwait(false);

            return(resultEx);
        }
Example #24
0
        protected async Task <AuthenticationResultEx> SendTokenRequestByRefreshTokenAsync(string refreshToken)
        {
            var requestParameters = new DictionaryRequestParameters(this.Resource, this.ClientKey);

            requestParameters[OAuthParameter.GrantType]    = OAuthGrantType.RefreshToken;
            requestParameters[OAuthParameter.RefreshToken] = refreshToken;
            requestParameters[OAuthParameter.Scope]        = OAuthValue.ScopeOpenId;

            AuthenticationResultEx result = await this.SendHttpMessageAsync(requestParameters).ConfigureAwait(false);

            if (result.RefreshToken == null)
            {
                result.RefreshToken = refreshToken;

                var msg = "Refresh token was missing from the token refresh response, so the refresh token in the request is returned instead";
                CallState.Logger.Verbose(this.CallState, msg);
                CallState.Logger.VerbosePii(this.CallState, msg);
            }

            return(result);
        }
        public void GetResultTest()
        {
            TokenResponse response = new TokenResponse();

            response.IdToken =
                "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1uQ19WWmNBVGZNNXBPWWlKSE1iYTlnb0VLWSIsImtpZCI6Ik1uQ19WWmNBVGZNNXBPWWlKSE1iYTlnb0VLWSJ9.eyJhdWQiOiI3YzdhMmY3MC1jYWVmLTQ1YzgtOWE2Yy0wOTE2MzM1MDFkZTQiLCJpc3MiOiJodHRwczovL2xvZ2luLm1pY3Jvc29mdG9ubGluZS5jb20vODE2OTAyODYtNTA1NC00Zjk3LWI3MDgtNTQxNjU0Y2Q5MjFhL3YyLjAvIiwiaWF0IjoxNDU1NTc2MjM1LCJuYmYiOjE0NTU1NzYyMzUsImV4cCI6MTQ1NTU4MDEzNSwibmFtZSI6IkFEQUwgT2JqLUMgLSBFMkUiLCJvaWQiOiIxZTcwYThlZi1jYjIwLTQxOWMtYjhhNy1hNDJlZDJmYTIyNzciLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJlMmVAYWRhbG9iamMub25taWNyb3NvZnQuY29tIiwic3ViIjoibHJxVDlsQXQzSUlhS3hHanE2UlNReFRqN3diV3Q2RnpaMFU3NkJZMEJINCIsInRpZCI6IjgxNjkwMjg2LTUwNTQtNGY5Ny1iNzA4LTU0MTY1NGNkOTIxYSIsInZlciI6IjIuMCJ9.axS_-N3Z3b1GnZftxb6dKtMeooldoIQ_B7YrVO4CQI9xhHI1_Vl-dXfsFHBPRvIvXBEfBEehaaWq9B9P_CD5TpQXGycsYS08knHf_QpHIJ9WQbBIJ774divakx7kN6x7IxjoD1PrfRfo2QZsLLAz-1n-NHt7FwtkBQpKTDfgc6cVShy9isaJt5WoxfUM1eNo1HK_YjHj7Q5-n-XiZEbe-8m-7nqwBw86QDlLdk7dBhhCzVzXZb_5HCHI-23xZLYR34RoW7ljYEG4P8auEcML1haS4MN83VKRorMyljAIoA4YOgbfnvnlAlxRz_rtAAcjNqaUpIwzadGzd-QVbyoKPQ";
            response.AccessToken   = "access-token";
            response.ExpiresIn     = 3599;
            response.CorrelationId = "correlation-id";
            response.RefreshToken  = "refresh-token";
            response.FamilyId      = "1";
            response.Scope         = "scope1 scope2";
            response.TokenType     = "Bearer";

            AuthenticationResultEx resultEx = response.GetResultEx();

            Assert.IsNotNull(resultEx);
            Assert.AreEqual("access-token", resultEx.Result.Token);
            Assert.AreEqual("scope1 scope2", resultEx.Result.ScopeSet.AsSingleString());
            Assert.AreEqual("Bearer", resultEx.Result.TokenType);
        }
        internal async Task <AuthenticationResultEx> RefreshAccessTokenAsync(AuthenticationResultEx result)
        {
            AuthenticationResultEx newResultEx = null;

            if (this.Scope != null)
            {
                PlatformPlugin.Logger.Verbose(this.CallState, "Refreshing access token...");

                try
                {
                    newResultEx = await this.SendTokenRequestByRefreshTokenAsync(result.RefreshToken).ConfigureAwait(false);

                    this.Authenticator.UpdateTenantId(result.Result.TenantId);

                    if (newResultEx.Result.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.
                        newResultEx.Result.UpdateTenantAndUser(result.Result.TenantId, result.Result.IdToken, result.Result.User);
                    }
                }
                catch (MsalException ex)
                {
                    MsalServiceException serviceException = ex as MsalServiceException;
                    if (serviceException != null && serviceException.ErrorCode == "invalid_request")
                    {
                        throw new MsalServiceException(
                                  MsalError.FailedToRefreshToken,
                                  MsalErrorMessage.FailedToRefreshToken + ". " + serviceException.Message,
                                  serviceException.ServiceErrorCodes,
                                  serviceException.InnerException);
                    }

                    newResultEx = new AuthenticationResultEx {
                        Exception = ex
                    };
                }
            }

            return(newResultEx);
        }
        private async Task <AuthenticationResultEx> SendHttpMessageAsync(IRequestParameters requestParameters)
        {
            string endpoint = this.Authenticator.TokenUri;

            endpoint = AddPolicyParameter(endpoint);

            var client = new MsalHttpClient(endpoint, this.CallState)
            {
                Client = { BodyParameters = requestParameters }
            };
            TokenResponse tokenResponse = await client.GetResponseAsync <TokenResponse>(ClientMetricsEndpointType.Token).ConfigureAwait(false);

            AuthenticationResultEx resultEx = tokenResponse.GetResultEx();

            if (resultEx.Result.ScopeSet == null || resultEx.Result.ScopeSet.Count == 0)
            {
                resultEx.Result.ScopeSet = this.Scope;
                PlatformPlugin.Logger.Information(this.CallState, "Scope was missing from the token response, so using developer provided scopes in the result");
            }

            return(resultEx);
        }
Example #28
0
        protected override async Task PostTokenRequestAsync(AuthenticationResultEx resultEx)
        {
            await base.PostTokenRequestAsync(resultEx).ConfigureAwait(false);

            UserInfo userInfo = resultEx.Result.UserInfo;

            this.UniqueId      = (userInfo == null) ? null : userInfo.UniqueId;
            this.DisplayableId = (userInfo == null) ? null : userInfo.DisplayableId;
            if (resultEx.ResourceInResponse != null)
            {
                this.Resource = resultEx.ResourceInResponse;

                var msg = "Resource value in the token response was used for storing tokens in the cache";
                CallState.Logger.Verbose(this.CallState, msg);
                CallState.Logger.VerbosePii(this.CallState, msg);
            }

            // If resource is not passed as an argument and is not returned by STS either,
            // we cannot store the token in the cache with null resource.
            // TODO: Store refresh token though if STS supports MRRT.
            this.StoreToCache = this.StoreToCache && (this.Resource != null);
        }
        protected override async Task PostTokenRequestAsync(AuthenticationResultEx resultEx)
        {
            await base.PostTokenRequestAsync(resultEx).ConfigureAwait(false);

            if ((this.DisplayableId == null && this.UniqueId == null) || this.UserIdentifierType == UserIdentifierType.OptionalDisplayableId)
            {
                return;
            }

            string uniqueId      = (resultEx.Result.UserInfo != null && resultEx.Result.UserInfo.UniqueId != null) ? resultEx.Result.UserInfo.UniqueId : "NULL";
            string displayableId = (resultEx.Result.UserInfo != null) ? resultEx.Result.UserInfo.DisplayableId : "NULL";

            if (this.UserIdentifierType == UserIdentifierType.UniqueId && string.Compare(uniqueId, this.UniqueId, StringComparison.Ordinal) != 0)
            {
                throw new AdalUserMismatchException(this.UniqueId, uniqueId);
            }

            if (this.UserIdentifierType == UserIdentifierType.RequiredDisplayableId && string.Compare(displayableId, this.DisplayableId, StringComparison.OrdinalIgnoreCase) != 0)
            {
                throw new AdalUserMismatchException(this.DisplayableId, displayableId);
            }
        }
        public void OBOUserAssertionHashNotFoundTest()
        {
            TokenCache    cache         = TokenCacheHelper.CreateCacheWithItems();
            string        someAssertion = "some-assertion-passed-by-developer";
            TokenCacheKey key           = cache.tokenCacheDictionary.Keys.First();

            //update cache entry with hash of an assertion that will not match
            cache.tokenCacheDictionary[key].UserAssertionHash =
                new CryptographyHelper().CreateSha256Hash(someAssertion + "-but-not-in-cache");

            ConfidentialClientApplication app = new ConfidentialClientApplication(TestConstants.DefaultClientId,
                                                                                  TestConstants.DefaultRedirectUri, new ClientCredential(TestConstants.DefaultClientSecret), new TokenCache());

            app.UserTokenCache = cache;

            string[] scope = { "mail.read" };
            HttpMessageHandlerFactory.MockHandler = new MockHttpMessageHandler()
            {
                Method          = HttpMethod.Post,
                ResponseMessage =
                    MockHelpers.CreateSuccessTokenResponseMessage("unique_id_3", "*****@*****.**", "root_id_3",
                                                                  scope)
            };

            UserAssertion assertion          = new UserAssertion(someAssertion, AssertionType);
            Task <AuthenticationResult> task = app.AcquireTokenOnBehalfOfAsync(key.Scope.AsArray(),
                                                                               assertion, key.Authority, TestConstants.DefaultPolicy);
            AuthenticationResult result = task.Result;

            Assert.IsNotNull(result);
            Assert.AreEqual("unique_id_3", result.User.UniqueId);
            Assert.AreEqual("*****@*****.**", result.User.DisplayableId);

            //check for new assertion Hash
            AuthenticationResultEx resultEx =
                cache.tokenCacheDictionary.Values.First(r => r.Result.User.UniqueId.Equals("unique_id_3"));

            Assert.AreEqual(HashAccessToken, resultEx.UserAssertionHash);
        }