Esempio n. 1
0
        public void GetExactScopesMatchedAccessTokenTest()
        {
            var atItem = Credential.CreateAccessToken(
                MsalTestConstants.HomeAccountId,
                MsalTestConstants.ProductionPrefNetworkEnvironment,
                new Uri(MsalTestConstants.AuthorityTestTenant).GetRealm(),
                MsalTestConstants.ClientId,
                ScopeUtils.JoinScopes(MsalTestConstants.Scope),
                TimeUtils.GetSecondsFromEpochNow(),
                TimeUtils.GetSecondsFromEpochNow() + MsalCacheV2TestConstants.ValidExpiresIn,
                TimeUtils.GetSecondsFromEpochNow() + MsalCacheV2TestConstants.ValidExtendedExpiresIn,
                TheSecret,
                string.Empty);

            _storageWorker.WriteCredentials(
                new List <Credential>
            {
                atItem
            });

            using (var httpManager = new MockHttpManager())
            {
                var serviceBundle = ServiceBundle.CreateWithCustomHttpManager(httpManager);

                var cacheManager = new CacheManager(
                    _storageManager,
                    new AuthenticationRequestParameters
                {
                    Account = MsalTestConstants.User,

                    // TODO:  In MSALC++, the request parameters only really needs the
                    // Authority URI itself since the cache isn't meant to
                    // do ANY network calls.
                    // So it would be great if we could reduce the complexity/dependencies
                    // here and do any of the validated authority cache / instance discovery
                    // outside of the context of the authentication parameters and
                    // cache interaction and just track the authority we're using...

                    // AccountId = MsalTestConstants.HomeAccountId,
                    // Authority = new Uri(MsalTestConstants.AuthorityTestTenant),
                    Authority = Authority.CreateAuthority(
                        serviceBundle,
                        MsalTestConstants.AuthorityTestTenant,
                        false),
                    ClientId = MsalTestConstants.ClientId,
                    Scope    = new SortedSet <string>(MsalCacheV2TestConstants.Scope) // todo(mzuber):  WHY SORTED SET?
                });

                Assert.IsTrue(cacheManager.TryReadCache(out var tokenResponse, out var accountResponse));
                Assert.IsNotNull(tokenResponse);
                Assert.IsNull(accountResponse);

                Assert.AreEqual(TheSecret, tokenResponse.AccessToken);
            }
        }
 public MsalTokenResponse ToMsalTokenResponse()
 {
     return(new MsalTokenResponse
     {
         AccessToken = AccessToken,
         ExpiresIn = Convert.ToInt64(DateTime.UtcNow.Subtract(ExpiresOn).TotalSeconds),
         ExtendedExpiresIn = Convert.ToInt64(DateTime.UtcNow.Subtract(ExtendedExpiresOn).TotalSeconds),
         Claims = string.Empty,
         ClientInfo = RawClientInfo,
         IdToken = IdToken.ToString(),
         RefreshToken = RefreshToken,
         Scope = ScopeUtils.JoinScopes(GrantedScopes),
         TokenType = "whatgoeshere",  // TODO: figure out MsalTokenResponse TokenType value(s)
     });
 }
Esempio n. 3
0
        /// <inheritdoc />
        public bool TryReadCache(out MsalTokenResponse msalTokenResponse, out IAccount account)
        {
            msalTokenResponse = null;
            account           = null;

            string homeAccountId = _authParameters.Account.HomeAccountId.Identifier;
            var    authority     = new Uri(_authParameters.Authority.CanonicalAuthority);
            string environment   = authority.GetEnvironment();
            string realm         = authority.GetRealm();
            string clientId      = _authParameters.ClientId;
            string target        = ScopeUtils.JoinScopes(_authParameters.Scope);

            if (string.IsNullOrWhiteSpace(homeAccountId) || string.IsNullOrWhiteSpace(environment) ||
                string.IsNullOrWhiteSpace(realm) || string.IsNullOrWhiteSpace(clientId) || string.IsNullOrWhiteSpace(target))
            {
                msalTokenResponse = null;
                account           = null;
                return(false);
            }

            var credentialsResponse = _storageManager.ReadCredentials(
                string.Empty,
                homeAccountId,
                environment,
                realm,
                clientId,
                string.Empty,
                target,
                new HashSet <CredentialType>
            {
                CredentialType.OAuth2AccessToken,
                CredentialType.OAuth2RefreshToken,
                CredentialType.OidcIdToken
            });

            if (credentialsResponse.Status.StatusType != OperationStatusType.Success)
            {
                // error reading credentials from the cache
                return(false);
            }

            if (!credentialsResponse.Credentials.Any())
            {
                // no credentials found in the cache
                return(false);
            }

            if (credentialsResponse.Credentials.ToList().Count > 3)
            {
                // expected to read up to 3 credentials from cache, somehow read more...
            }

            Credential accessToken  = null;
            Credential refreshToken = null;
            Credential idToken      = null;

            foreach (var credential in credentialsResponse.Credentials)
            {
                switch (credential.CredentialType)
                {
                case CredentialType.OAuth2AccessToken:
                    if (accessToken != null)
                    {
                        // warning, more than one access token read from cache
                    }

                    accessToken = credential;
                    break;

                case CredentialType.OAuth2RefreshToken:
                    if (refreshToken != null)
                    {
                        // warning, more than one refresh token read from cache
                    }

                    refreshToken = credential;
                    break;

                case CredentialType.OidcIdToken:
                    if (idToken != null)
                    {
                        // warning, more than one idtoken read from cache
                    }

                    idToken = credential;
                    break;

                default:
                    // warning unknown credential type
                    break;
                }
            }

            if (idToken == null)
            {
                // warning, no id token
            }

            if (accessToken == null)
            {
                // warning no access token
            }
            else if (!IsAccessTokenValid(accessToken))
            {
                DeleteCachedAccessToken(
                    homeAccountId,
                    environment,
                    realm,
                    clientId,
                    target);
                accessToken = null;
            }

            if (accessToken != null)
            {
                refreshToken = null; // there's no need to return a refresh token, just the access token
            }
            else if (refreshToken == null)
            {
                // warning, no valid access token and no refresh token found in cache
                return(false);
            }

            IdToken idTokenJwt = null;

            if (idToken != null)
            {
                idTokenJwt = new IdToken(idToken.Secret);
            }

            if (accessToken != null)
            {
                var accountResponse = _storageManager.ReadAccount(string.Empty, homeAccountId, environment, realm);
                if (accountResponse.Status.StatusType != OperationStatusType.Success)
                {
                    // warning, error reading account from cache
                }
                else
                {
                    account = accountResponse.Account;
                }

                if (account == null)
                {
                    // warning, no account in cache, will still return token if found
                }
            }

            msalTokenResponse = new TokenResponse(idTokenJwt, accessToken, refreshToken).ToMsalTokenResponse();
            return(true);
        }
Esempio n. 4
0
        /// <inheritdoc />
        public IAccount CacheTokenResponse(MsalTokenResponse msalTokenResponse)
        {
            var tokenResponse = new TokenResponse(msalTokenResponse);

            string homeAccountId = GetHomeAccountId(tokenResponse);
            var    authority     = new Uri(_authParameters.Authority.CanonicalAuthority);
            string environment   = authority.GetEnvironment();
            string realm         = authority.GetRealm();
            string clientId      = _authParameters.ClientId;
            string target        = ScopeUtils.JoinScopes(tokenResponse.GrantedScopes);

            if (string.IsNullOrWhiteSpace(homeAccountId) || string.IsNullOrWhiteSpace(environment) ||
                string.IsNullOrWhiteSpace(realm) || string.IsNullOrWhiteSpace(clientId) || string.IsNullOrWhiteSpace(target))
            {
                // skipping writing to the cache, PK is empty
                return(null);
            }

            var  credentialsToWrite = new List <Credential>();
            long cachedAt           = DateTime.UtcNow.Ticks; // todo: this is probably wrong

            if (tokenResponse.HasRefreshToken)
            {
                credentialsToWrite.Add(
                    Credential.CreateRefreshToken(
                        homeAccountId,
                        environment,
                        clientId,
                        cachedAt,
                        tokenResponse.RefreshToken,
                        string.Empty));
            }

            if (tokenResponse.HasAccessToken)
            {
                long expiresOn         = tokenResponse.ExpiresOn.Ticks;         // todo: this is probably wrong
                long extendedExpiresOn = tokenResponse.ExtendedExpiresOn.Ticks; // todo: this is probably wrong

                var accessToken = Credential.CreateAccessToken(
                    homeAccountId,
                    environment,
                    realm,
                    clientId,
                    target,
                    cachedAt,
                    expiresOn,
                    extendedExpiresOn,
                    tokenResponse.AccessToken,
                    string.Empty);
                if (IsAccessTokenValid(accessToken))
                {
                    credentialsToWrite.Add(accessToken);
                }
            }

            var idTokenJwt = tokenResponse.IdToken;

            if (!idTokenJwt.IsEmpty)
            {
                credentialsToWrite.Add(
                    Credential.CreateIdToken(
                        homeAccountId,
                        environment,
                        realm,
                        clientId,
                        cachedAt,
                        idTokenJwt.Raw,
                        string.Empty));
            }

            var status = _storageManager.WriteCredentials(string.Empty, credentialsToWrite);

            if (status.StatusType != OperationStatusType.Success)
            {
                // warning error writing to cache
            }

            // if id token jwt is empty, return null

            string localAccountId = GetLocalAccountId(idTokenJwt);
            var    authorityType  = GetAuthorityType();

            var account = Microsoft.Identity.Client.CacheV2.Schema.Account.Create(
                homeAccountId,
                environment,
                realm,
                localAccountId,
                authorityType,
                idTokenJwt.PreferredUsername,
                idTokenJwt.GivenName,
                idTokenJwt.FamilyName,
                idTokenJwt.MiddleName,
                idTokenJwt.Name,
                idTokenJwt.AlternativeId,
                tokenResponse.RawClientInfo,
                string.Empty);

            status = _storageManager.WriteAccount(string.Empty, account);

            if (status.StatusType != OperationStatusType.Success)
            {
                // warning error writing account to cache
            }

            return(account);
        }