/// <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"); } }
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); }