/// <summary>
        /// Figures out the authority based on the authority from the config and the authority from the request,
        /// and optionally the homeAccountTenantId, which has an impact on AcquireTokenSilent
        ///
        /// The algorithm is:
        ///
        /// 1. If there is no request authority (i.e. no authority override), use the config authority.
        ///     1.1. For AAD, if the config authority is "common" etc, try to use the tenanted version with the home account tenant ID
        /// 2. If there is a request authority, try to use it.
        ///     2.1. If the request authority is not "common", then use it
        ///     2.2  If the request authority is "common", ignore it, and use 1.1
        ///
        /// Special cases:
        ///
        /// - if the authority is not defined at the application level and the request level is not AAD, use the request authority
        /// - if the authority is defined at app level, and the request level authority of is of different type, throw an exception
        ///
        /// </summary>
        public static async Task <Authority> CreateAuthorityForRequestAsync(
            RequestContext requestContext,
            AuthorityInfo requestAuthorityInfo,
            string requestHomeAccountTenantId = null)
        {
            var configAuthorityInfo = requestContext.ServiceBundle.Config.AuthorityInfo;

            if (configAuthorityInfo == null)
            {
                throw new ArgumentNullException(nameof(configAuthorityInfo));
            }

            ValidateTypeMismatch(configAuthorityInfo, requestAuthorityInfo);
            await ValidateSameHostAsync(requestAuthorityInfo, requestContext).ConfigureAwait(false);

            switch (configAuthorityInfo.AuthorityType)
            {
            // ADFS and B2C are tenant-less, no need to consider tenant
            case AuthorityType.Adfs:
                return(requestAuthorityInfo == null ?
                       new AdfsAuthority(configAuthorityInfo) :
                       new AdfsAuthority(requestAuthorityInfo));

            case AuthorityType.B2C:

                if (requestAuthorityInfo != null)
                {
                    return(new B2CAuthority(requestAuthorityInfo));
                }
                return(new B2CAuthority(configAuthorityInfo));

            case AuthorityType.Aad:

                if (requestAuthorityInfo == null)
                {
                    return(CreateAuthorityWithTenant(configAuthorityInfo, requestHomeAccountTenantId));
                }

                // In case the authority is defined only at the request level
                if (configAuthorityInfo.IsDefaultAuthority &&
                    requestAuthorityInfo.AuthorityType != AuthorityType.Aad)
                {
                    return(CreateAuthority(requestAuthorityInfo));
                }

                var requestAuthority = new AadAuthority(requestAuthorityInfo);
                if (!requestAuthority.IsCommonOrganizationsOrConsumersTenant())
                {
                    return(requestAuthority);
                }

                return(CreateAuthorityWithTenant(configAuthorityInfo, requestHomeAccountTenantId));

            default:
                throw new MsalClientException(
                          MsalError.InvalidAuthorityType,
                          "Unsupported authority type");
            }
        }
        /// <summary>
        /// Figures out the authority based on the authority from the config and the authority from the request,
        /// and optionally the homeAccountTenantId, which has an impact on AcquireTokenSilent
        ///
        /// The algorithm is:
        ///
        /// 1. If there is no request authority (i.e. no authority override), use the config authority.
        ///     1.1. For AAD, if the config authority is "common" etc, try to use the tenanted version with the home account tenant ID
        /// 2. If there is a request authority, try to use it.
        ///     2.1. If the request authority is not "common", then use it
        ///     2.2  If the request authority is "common", ignore it, and use 1.1
        ///
        /// Special cases:
        ///
        /// - if the authority is not defined at the application level and the request level is not AAD, use the request authority
        /// - if the authority is defined at app level, and the request level authority of is of different type, throw an exception
        ///
        /// </summary>
        public static Authority CreateAuthorityForRequest(
            AuthorityInfo configAuthorityInfo,
            AuthorityInfo requestAuthorityInfo,
            string requestHomeAccountTenantId = null)
        {
            if (configAuthorityInfo == null)
            {
                throw new ArgumentNullException(nameof(configAuthorityInfo));
            }

            ValidateTypeMismatch(configAuthorityInfo, requestAuthorityInfo);

            switch (configAuthorityInfo.AuthorityType)
            {
            // ADFS and B2C are tenant-less, no need to consider tenant
            case AuthorityType.Adfs:
                return(requestAuthorityInfo == null ?
                       new AdfsAuthority(configAuthorityInfo) :
                       new AdfsAuthority(requestAuthorityInfo));

            case AuthorityType.B2C:

                if (requestAuthorityInfo != null)
                {
                    CheckB2CAuthorityHost(requestAuthorityInfo, configAuthorityInfo);
                    return(new B2CAuthority(requestAuthorityInfo));
                }
                return(new B2CAuthority(configAuthorityInfo));

            case AuthorityType.Aad:

                if (requestAuthorityInfo == null)
                {
                    return(CreateAuthorityWithTenant(configAuthorityInfo, requestHomeAccountTenantId));
                }

                // In case the authority is defined only at the request level
                if (configAuthorityInfo.IsDefaultAuthority &&
                    requestAuthorityInfo.AuthorityType != AuthorityType.Aad)
                {
                    return(CreateAuthority(requestAuthorityInfo));
                }

                var requestAuthority = new AadAuthority(requestAuthorityInfo);
                if (!requestAuthority.IsCommonOrganizationsOrConsumersTenant())
                {
                    return(requestAuthority);
                }

                return(CreateAuthorityWithTenant(configAuthorityInfo, requestHomeAccountTenantId));

            default:
                throw new MsalClientException(
                          MsalError.InvalidAuthorityType,
                          "Unsupported authority type");
            }
        }
예제 #3
0
        internal override string GetTenantedAuthority(string tenantId, bool forceSpecifiedTenant = false)
        {
            if (!string.IsNullOrEmpty(tenantId) &&
                (forceSpecifiedTenant || AadAuthority.IsCommonOrganizationsOrConsumersTenant(TenantId)))
            {
                var authorityUri = new Uri(AuthorityInfo.CanonicalAuthority);

                return(string.Format(
                           CultureInfo.InvariantCulture,
                           DstsCanonicalAuthorityTemplate,
                           authorityUri.Authority,
                           tenantId));
            }

            return(AuthorityInfo.CanonicalAuthority);
        }