We have implemented Sitecore Federated Authentication with Azure AD (similar to http://sitecore.badalkotecha.com/2017/11/federated-authentication-for-sitecore-9-integrating-with-azuread.html). Now we have a requirement to add two more sites (multisite) with same tenant id. In short 3 webSites, 1 TenantId and 3 ClientIds. we have extended the owin.identityProviders -> processor and redirecting the user to microsoft login along with ClientId and RedirectUrl. But the processor is always pointing to one ClientID. Please suggest how to achieve Sitecore Federated Authentication with Azure AD for Multisite.
AzureAD Config
<setting name="Site2_ClientId" value="yyyyyyy" />
<setting name="Site2_SecretKey" value="yyyyyyy" />
<setting name="Site2_RedirectURL" value="https://Site2.domainName.com" />
<setting name="Site3_ClientId" value="zzzzzzz" />
<setting name="Site3_SecretKey" value="zzzzzzzz" />
<setting name="Site3_RedirectURL" value="https://Site3.domainName.com" />
</settings>
<pipelines>
<owin.identityProviders>
<processor type="xxxxxxx.Foundation.ScExtensions.Pipeline.AzureADFedAuthProcessor, xxxxxxx.Foundation.ScExtensions" resolve="true">
</processor>
</owin.identityProviders>
</pipelines>
<federatedAuthentication>
<identityProviders hint="list:AddIdentityProvider">
<identityProvider id="xxxxxxx.sc.azureAD" type="Sitecore.Owin.Authentication.Configuration.DefaultIdentityProvider, Sitecore.Owin.Authentication">
<param desc="name">$(id)</param>
<param desc="domainManager" type="Sitecore.Abstractions.BaseDomainManager" resolve="true" />
<caption>SignIn</caption>
<domain>extranet</domain>
<enabled>true</enabled>
<icon>/sitecore/shell/themes/standard/Images/24x24/msazure.png</icon>
<transformations hint="list:AddTransformation">
<!--
Transformations
-->
</transformations>
</identityProvider>
</identityProviders>
<!-- Property initializer assigns claim values to sitecore user properties -->
<propertyInitializer type="Sitecore.Owin.Authentication.Services.PropertyInitializer, Sitecore.Owin.Authentication">
<maps hint="list">
<!--
CLAIMS MAPPING
-->
</maps>
</propertyInitializer>
<identityProvidersPerSites>
<mapEntry name="all" type="Sitecore.Owin.Authentication.Collections.IdentityProvidersPerSitesMapEntry, Sitecore.Owin.Authentication" resolve="true">
<sites hint="list">
<site>WebSite1</site>
<site>WebSite2</site>
<site>WebSite3</site>
</sites>
<!-- Registered identity providers for above providers -->
<identityProviders hint="list:AddIdentityProvider">
<identityProvider ref="federatedAuthentication/identityProviders/identityProvider[@id='xxxxxxx.sc.azureAD']" />
</identityProviders>
<!-- ExternalUserBuilder is what creates a user with customusername in Sitecore and assigns roles based on claim transformation configured above -->
<externalUserBuilder type="Sitecore.Owin.Authentication.Services.DefaultExternalUserBuilder, Sitecore.Owin.Authentication" resolve="true">
<param desc="isPersistentUser">false</param>
</externalUserBuilder>
</mapEntry>
<mapEntry name="sites with the web database" type="Sitecore.Owin.Authentication.Collections.IdentityProvidersPerSitesMapEntry, Sitecore.Owin.Authentication" resolve="true">
<sites hint="list">
<site>database:web</site>
</sites>
<identityProviders hint="list:AddIdentityProvider">
<identityProvider ref="federatedAuthentication/identityProviders/identityProvider[@id='xxxxxxx.sc.azureAD']" />
</identityProviders>
</mapEntry>
<mapEntry name="all sites" type="Sitecore.Owin.Authentication.Collections.IdentityProvidersPerSitesMapEntry, Sitecore.Owin.Authentication" resolve="true">
<sites hint="list">
<site>regexp:.*</site>
</sites>
<identityProviders hint="list:AddIdentityProvider">
<identityProvider ref="federatedAuthentication/identityProviders/identityProvider[@id='xxxxxxx.sc.azureAD']" />
</identityProviders>
<externalUserBuilder type="Sitecore.Owin.Authentication.Services.DefaultExternalUserBuilder, Sitecore.Owin.Authentication" resolve="true">
<IsPersistentUser>true</IsPersistentUser>
</externalUserBuilder>
</mapEntry>
</identityProvidersPerSites>
</federatedAuthentication>
<sites>
<site name="WebSite1" requireLogin="true" loginPage="/api/sitecore/login/Site1SignIn"/>
<site name="WebSite2" requireLogin="true" loginPage="/api/sitecore/login/Site2SignIn"/>
<site name="WebSite3" requireLogin="true" loginPage="/api/sitecore/login/Site3SignIn"/>
</sites>
Processor Code
public AzureADFedAuthProcessor(FederatedAuthenticationConfiguration federatedAuthenticationConfiguration, ICookieManager cookieManager, BaseSettings settings) : base(federatedAuthenticationConfiguration, cookieManager, settings)
{
federatedAuthenticationConfigurationLocal = federatedAuthenticationConfiguration;
}
protected override string IdentityProviderName => "xxxxxx.sc.azureAD";
protected override void ProcessCore([NotNull] IdentityProvidersArgs args)
{
Assert.ArgumentNotNull(args, nameof(args));
try
{
var identityProvider = this.GetIdentityProvider();
var authenticationType = this.GetAuthenticationType();
string tenant = Settings.GetSetting("Tenant");
string postLogoutRedirectURI = Settings.GetSetting("PostLogoutRedirectURI");
string aadInstance = Settings.GetSetting("AADInstance");
string clientId, redirectURI;
clientId = Settings.GetSetting("Site1_ClientId");
redirectURI = Settings.GetSetting("Site1_RedirectURL");
//WE NEED SOMETHING SIMILAR TO THIS
//if (Session[Site] == webSite1)
//{
// clientId = Settings.GetSetting("Site1_ClientId");
// redirectURI = Settings.GetSetting("Site1_RedirectURL");
//}
//else if (webSite2)
//{
// clientId = Settings.GetSetting("Site2_ClientId");
// redirectURI = Settings.GetSetting("Site2_RedirectURL");
//}
//else
//{
// clientId = Settings.GetSetting("Site3_ClientId");
// redirectURI = Settings.GetSetting("Site3_RedirectURL");
//}
string authority = string.Format(CultureInfo.InvariantCulture, aadInstance, tenant);
args.App.UseCookieAuthentication(new Microsoft.Owin.Security.Cookies.CookieAuthenticationOptions()
{
CookieManager = new SystemWebCookieManager()
});
args.App.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
Caption = identityProvider.Caption,
AuthenticationType = authenticationType,
AuthenticationMode = AuthenticationMode.Passive,
ClientId = clientId,
Authority = authority,
PostLogoutRedirectUri = postLogoutRedirectURI,
RedirectUri = redirectURI,
Notifications = new OpenIdConnectAuthenticationNotifications
{
SecurityTokenValidated = notification =>
{
var identity = notification.AuthenticationTicket.Identity;
foreach (var claimTransformationService in identityProvider.Transformations)
{
claimTransformationService.Transform(identity, new TransformationContext
(
federatedAuthenticationConfigurationLocal, identityProvider
));
}
notification.AuthenticationTicket = new AuthenticationTicket(identity, notification.AuthenticationTicket.Properties);
return Task.CompletedTask;
}
}
});
}
catch(Exception ex)
{
Log.Error("AzureAD: Error in reaching out to AzureAD Authentication provider", ex, this);
}
}
}
Login Controller
public ActionResult SiteOneSignIn()
{
try
{
var url = "/";
if (!string.IsNullOrEmpty(Request.QueryString?["returnUrl"]))
url = Request.QueryString["returnUrl"];
var corePipelineManager = DependencyResolver.Current.GetService<BaseCorePipelineManager>();
var args = new GetSignInUrlInfoArgs("mysite", url);
GetSignInUrlInfoPipeline.Run(corePipelineManager, args);
return View("/Views/Login/Login.cshtml", args.Result);
}
catch (Exception ex)
{
Log.Error("Error in SignIn: ", ex, this);
return null;
}
}