Sitecore ADFS Integration with Sitecore Identity
Requirements
ADFS Server
Sitecore With SI
Assumptions
ADFS Server Already Exists
Sitecore with SI installed
Here are the steps to Implement ADFS
ADFS Changes
Create Groups in ADFS for all the roles in Sitecore and obtain the group id’s for each role from ADFS along with the following details
ClientId
ClientSecret
Authority
Metadata
GroupId
Add Users to ADFS groups
Code changes
Create a new C# .net Core Class Library project
Go to Project Properties and change the Target framework to .Net Standard 2.0
Go to Visual Studio Options and add Package Source to include Sitecore Identity Nuget with the following source
https://sitecore.myget.org/F/sc-identity/api/v3/index.json

Add the following Nuget Packages to your Project
Sitecore.Plugin.IdentityProviders
Microsoft.AspNetCore.Authentication
Microsoft.AspNetCore.Authentication.OpenIdConnect
Add “Ids4AdfsIdentityProvider.cs” file to the root of the project
namespace Adfs
{
public class Ids4AdfsIdentityProvider : Sitecore.Plugin.IdentityProviders.IdentityProvider
{
public string ClientId { get; set; }
public string ClientSecret { get; set; }
public string MetadataAddress { get; set; }
public string Authority { get; set; }
}
}
Add a configuration folder and Create a class called “AppSettings.cs
namespace Adfs.Configuration
{
public class AppSettings
{
public static readonly string SectionName = "Sitecore:ExternalIdentityProviders:IdentityProviders:Ids4Adfs";
public Ids4AdfsIdentityProvider Ids4AdfsIdentityProvider { get; set; } = new Ids4AdfsIdentityProvider();
}
}
Add “ConfigureSitecore.cs” file to root
using Adfs.Configuration;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using Sitecore.Framework.Runtime.Configuration;
using System;
using System.Security.Claims;
using System.Threading.Tasks;
namespace Adfs
{
public class ConfigureSitecore
{
private readonly ILogger<ConfigureSitecore> _logger;
private readonly AppSettings _appSettings;
public ConfigureSitecore(ISitecoreConfiguration scConfig, ILogger<ConfigureSitecore> logger)
{
this._logger = logger;
this._appSettings = new AppSettings();
scConfig.GetSection(AppSettings.SectionName);
scConfig.GetSection(AppSettings.SectionName).Bind((object)this._appSettings.Ids4AdfsIdentityProvider);
}
public void ConfigureServices(IServiceCollection services)
{
Ids4AdfsIdentityProvider identityProvider = this._appSettings.Ids4AdfsIdentityProvider;
if (!identityProvider.Enabled)
return;
this._logger.LogDebug("Configure '" + identityProvider.DisplayName + "'. AuthenticationScheme = " + identityProvider.AuthenticationScheme + ", ClientId = " + identityProvider.ClientId, Array.Empty<object>());
new AuthenticationBuilder(services).AddOpenIdConnect(identityProvider.AuthenticationScheme, identityProvider.DisplayName, (Action<OpenIdConnectOptions>)(options =>
{
options.SignInScheme = "idsrv.external";
options.SignOutScheme = "idsrv";
options.RequireHttpsMetadata = false;
options.SaveTokens = true;
options.Authority = identityProvider.Authority;
options.ClientId = identityProvider.ClientId;
options.ResponseType = "id_token";
options.MetadataAddress = identityProvider.MetadataAddress;
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "name",
RoleClaimType = "roles"
};
options.Events = new OpenIdConnectEvents()
{
OnTokenValidated = (context) =>
{
ClaimsIdentity identity = context.Principal.Identity as ClaimsIdentity;
return Task.FromResult(0);
}
};
}));
}
}
}
Build the Project and Copy the project dll
End of coding
SI changes
Add a new folder in wwwrootsitecore (e.g., Custom.Plugin.IdentityProvider.Ids4Adfs)
Add a manifest file Sitecore.Plugin.manifest in the new folder
<?xml version="1.0" encoding="utf-8"?>
<SitecorePlugin PluginName="Adfs.Ids4Adfs" AssemblyName="Adfs" Version="1.0.0">
<Dependencies>
<Dependency name="Sitecore.Plugin.IdentityProviders">4.0.0-r00257</Dependency>
</Dependencies>
<Tags>
<Sitecore>Sitecore</Sitecore>
</Tags>
</SitecorePlugin>
Add New folder with name “Config”
Add a new XML file (e.g., Custom.Plugin.IdentityProvider.Ids4Adfs.xml) and replace the tokens with ADFS values
<?xml version="1.0" encoding="utf-8"?>
<Settings>
<Sitecore>
<ExternalIdentityProviders>
<IdentityProviders>
<Ids4Adfs type="Sitecore.Plugin.IdentityProviders.IdentityProvider, Sitecore.Plugin.IdentityProviders">
<AuthenticationScheme>IdS4-Ids4Adfs</AuthenticationScheme>
<DisplayName>Login with ADFS</DisplayName>
<Enabled>true</Enabled>
<ClientId>#{ClientId}#</ClientId>
<ClientSecret>#{ClientSecret}#</ClientSecret>
<Authority>#{Authority}#</Authority>
<MetadataAddress>#{Metadata}#</MetadataAddress>
<ClaimsTransformations>
<ClaimsTransformation1 type="Sitecore.Plugin.IdentityProviders.DefaultClaimsTransformation, Sitecore.Plugin.IdentityProviders">
<SourceClaims>
<Claim1 type="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn" />
</SourceClaims>
<NewClaims>
<Claim1 type="email" />
</NewClaims>
</ClaimsTransformation1>
<!--Place transformation rules here. -->
<ClaimsTransformation2 type="Sitecore.Plugin.IdentityProviders.DefaultClaimsTransformation, Sitecore.Plugin.IdentityProviders">
<SourceClaims>
<Claim1 type="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" />
</SourceClaims>
<NewClaims>
<Claim1 type="name" />
</NewClaims>
</ClaimsTransformation2>
<AzureGroupTransformation type="Sitecore.Plugin.IdentityProviders.DefaultClaimsTransformation, Sitecore.Plugin.IdentityProviders">
<SourceClaims>
<Claim1 type="http://schemas.xmlsoap.org/claims/Group" value="#{GroupIdFromAdfs}#"/>
</SourceClaims>
<NewClaims>
<Claim1 type="http://www.sitecore.net/identity/claims/isAdmin" value="true" />
</NewClaims>
</AzureGroupTransformation>
</ClaimsTransformations>
</Ids4Adfs>
</IdentityProviders>
</ExternalIdentityProviders>
</Sitecore>
</Settings>
Note: the above xml maps only admin role, you can add more claims to the xml for other roles
Restart SI app and open sitecore login page and verify that Login to ADFS button is available
CM changes
Add a new patch config in Include folder for mapping roles for the claims setup in SI and replace the tokens with actual values
<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:role="http://www.sitecore.net/xmlconfig/role/" xmlns:set="http://www.sitecore.net/xmlconfig/set/">
<sitecore role:require="Standalone or ContentDelivery or ContentManagement">
<federatedAuthentication>
<identityProvidersPerSites>
<mapEntry name="all sites">
<identityProviders hint="list:AddIdentityProvider">
<identityProvider ref="federatedAuthentication/identityProviders/identityProvider[@id='SitecoreIdentityServer/IdS4-Ids4Adfs']" />
</identityProviders>
</mapEntry>
</identityProvidersPerSites>
<identityProviders>
<!-- An example of how to add an identity provider as a sub-provider of the Identity Server.
The 'name' property must be in the following format: SitecoreIdentityServer/[AuthenticationScheme], where the 'AuthenticationScheme' equals the
authentication scheme of an external identity provider that is configured on the Identity Server.
Notes:
1. The 'TriggerExternalSignOut' and 'Transformations' properties are inherited from the the Identity Server provider node and can not be overridden.
2. To use a sub-provider, the 'Enabled' property of the Identity Server provider must be set to 'Enabled'. -->
<identityProvider id="SitecoreIdentityServer/IdS4-Ids4Adfs" type="Sitecore.Owin.Authentication.Configuration.DefaultIdentityProvider, Sitecore.Owin.Authentication">
<param desc="name">$(id)</param>
<param desc="domainManager" type="Sitecore.Abstractions.BaseDomainManager" resolve="true" />
<caption>Log in with Sitecore Identity: Azure AD</caption>
<icon>/sitecore/shell/themes/standard/Images/24x24/msazure.png</icon>
<domain>sitecore</domain>
<transformations hint="list:AddTransformation">
<!-- you need to have an Idp Claim for this to work -->
<!-- This is to transform AD group into Sitecore Role. -->
<transformation name="Transform to Sitecore Author Role" type="Sitecore.Owin.Authentication.Services.DefaultTransformation, Sitecore.Owin.Authentication">
<sources hint="raw:AddSource">
<claim name="http://schemas.xmlsoap.org/claims/Group" value="#{GroupIdFromAdfs}#" />
</sources>
<targets hint="raw:AddTarget">
<claim name="http://schemas.microsoft.com/ws/2008/06/identity/claims/role" value="sitecoreAdmin" />
</targets>
<keepSource>true</keepSource>
</transformation>
</transformations>
</identityProvider>
</identityProviders>
</federatedAuthentication>
</sitecore>
</configuration>
Restart CM instance and try logging in to Sitecore using the Login to ADFS button
You will now be able to login with ADFS login and see the Sitecore launchpad with the features assigned to the logged in ADFS user.
This has been tested in Sitecore 9.3 and Sitecore 10.2