Home > .Net, C#, Sitecore 9, Uncategorized > Sitecore 9.1 IdentityServer On-Premise AD via ADFS

Sitecore 9.1 IdentityServer On-Premise AD via ADFS

Which the launch of Sitecore 9.1 came the introduction of the identity server to Sitecore list roles. You can find a lot more information about the Identity Server here https://identityserver.io/- Personally I think this I is great enhancement and add are more easy extendable way of enabling 3 party  authentication providers to Sitecore. As standard the Identity server runs on Sitecore  HOST https://doc.sitecore.com/developers/91/sitecore-experience-management/en/sitecore-host.html And ships with the possibility to use Azure AD and the Identiytserver.Contrib.Membership module  allowing for cloud AD and the old DB style of authenticating in Sitecore. This also means the the old Sitecore AD module is now deprecated and no longer supported. So in this blog post I will show how to integrated a On Premise Ad with  Sitecore Idenityserver hosted on Sitecore Host.

First you need a AD of course and then you need ADFS server to act as a authentication provide to the Identityserver. This however is a little out of scope for this post. But here is two great links on how to configure and forward AD groups as roles

https://docs.microsoft.com/en-us/windows-server/identity/ad-fs/operations/create-a-rule-to-send-group-membership-as-a-claim

https://stackoverflow.com/questions/55494354/user-groups-as-claims-through-openid-connect-over-adfs

Before we get to code you need to know about this nuget feed related to Sitcore Identity

https://sitecore.myget.org/F/sc-identity/api/v3/index.json

Since this feed contains some of packages needed. So this project or solution rather is to use OpenId Connect against the with the ADFS server

The solution consist of three class’ i will briefly show them here below

The App Settings classe seen below for retrieving the Setting for the Provider

public class AppSettings
{
public static readonly string SectionName = "Sitecore:ExternalIdentityProviders:IdentityProviders:ADFS";
public ADFSIdentityProvider ADFSIdentityProvider { get; set; } = new ADFSIdentityProvider();
}

The ADFSIdentityProvider which allows for a type strong way of accessing settings related to the module.

public class ADFSIdentityProvider
{
public bool Enabled { get; set; }
public string Authority { get; set; }
public string ClientId { get; set; }
public string AuthenticationScheme { get; set; }
public string MetadataAddress { get; set; }
public string DisplayName { get; set; }
}

And the CongifugreSitecore class which handles the communication with ADFS server

using System;
using System.Security.Claims;
using System.Threading.Tasks;
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;

namespace Sitecore.IdentityServer.ADFS
{
public class ConfigureSitecore
{
private readonly ILogger _logger;
private readonly AppSettings _appSettings;

public ConfigureSitecore(ISitecoreConfiguration scConfig, ILogger logger)
{

this._logger = logger;
this._appSettings = new AppSettings();
scConfig.GetSection(AppSettings.SectionName);
scConfig.GetSection(AppSettings.SectionName).Bind((object)this._appSettings.ADFSIdentityProvider);
}

public object IdentityServerConstants { get; private set; }

public void ConfigureServices(IServiceCollection services)
{
ADFSIdentityProvider adfsProvider = this._appSettings.ADFSIdentityProvider;
if (!adfsProvider.Enabled)
return;
_logger.LogDebug($"Adding ADFS clientId {adfsProvider.ClientId} Authority {adfsProvider.Authority} Scheme {adfsProvider.AuthenticationScheme}");
new AuthenticationBuilder(services).AddOpenIdConnect(adfsProvider.AuthenticationScheme, adfsProvider.DisplayName, (Action)(options =>
{

options.SignInScheme = "idsrv.external";
options.SignOutScheme = "idsrv";
options.RequireHttpsMetadata = false;
options.SaveTokens = true;
options.Authority = adfsProvider.Authority;
options.ClientId = adfsProvider.ClientId;
options.ResponseType = "id_token";
options.MetadataAddress = adfsProvider.MetadataAddress;
options.TokenValidationParameters = new TokenValidationParameters
{
NameClaimType = "name",
RoleClaimType = "roles"

};
//Added to enable DEBUG to see all claims
//Can be removed in production
options.Events = new OpenIdConnectEvents()
{
OnTokenValidated = (context) =>
{
//This identity include all claims
ClaimsIdentity identity = context.Principal.Identity as ClaimsIdentity;
//ADD break POINT to see all the claims,
return Task.FromResult(0);
}
};
}));

}
}
}

With the solution build you can deploy this to your Identity Server in sitecoreruntime folder in a production folder. The installationor placement of files should look like below.

isplace

The Sitecore Plugin manifest should point to your assembly name  an example given below.

idenxml1

And for the configuration files placed in Config folder is here an examplereplace clientid and autherityaddress and metaaddress with your own values

identiyseraddfxml2

with that in place you can go ahead and restart the application pool for the identityserver to load in the configurations and you should see the AD login button.

adfslogin

clicking on the button should take you t your ADFS server for authentication, after taht you should be redirect to Sitecore.

Mapping of claims to roles works the same as with Sitecore Azure Ad implementation.

You can find the code for this on github

https://github.com/istern/Sitecore.IdentityServer.ADFS

 

Advertisements
  1. Corey Burnett
    15/05/2019 at 17:30

    I am having problems with your code for the ConfigureServices method. Can you double check that it is pasted in to this blog post correctly? I see some &gt that I suspect are supposed to be greater than signs. I get errors in Visual Studio saying “Delegate Action does not take 1 argument”

    • 15/05/2019 at 17:39

      Sorry I will try to verify the pasted code, did you try the code from github ?

  2. Corey Burnett
    15/05/2019 at 18:20

    There was one more error that I fixed. It’s on line 36. It should read Action. Thanks!

    • 15/05/2019 at 18:23

      So the GitHub part worked ?

      • Corey Burnett
        15/05/2019 at 18:35

        Yes the code in GitHub compiled properly. The code in this post has an error on line 36 in the ConfigureSitecore class.

      • 15/05/2019 at 18:37

        Perfect thank you for the update. Let me know if you have any issues.

      • 15/05/2019 at 19:49

        I’ve updated the code in post to reflect it

  3. Corey Burnett
    15/05/2019 at 20:01

    Is there something I have to do in Sitecore config to get this custom ADFS sign in to show up? I have followed everything in your post but when I go to sign in I don’t see AD as an option. Is there some config I have to do to tell Sitecore to use this new custom ADFS authentication provider?

    • 15/05/2019 at 20:04

      Have you placed everything as shown in the image under the sitecoreruntime folder ? and have you also recycled the identityserver apppool ?

      • Corey Burnett
        15/05/2019 at 20:21

        Yes I have placed everything as shown in the image. And I have recycled the IdentityServer app pool. I see a button that says “Go to login” (which is the default after installing 9.1). I don’t see “AD”.

      • 16/05/2019 at 07:38

        Argh okay no I get it you’re not on the Identityserver please try to enter the url for the identityServer in your browser instead of hitting Sitecore directly. Remember to use https.

      • Corey Burnett
        15/05/2019 at 20:23

        Also it is difficult to tell from the image exactly where the files are supposed to go. Does my DLL go in the “production” folder or the “sitecore” folder?

      • 15/05/2019 at 20:27

        it goes it to the production folder.
        can you see this in message in the log “Adding ADFS clientId…….”
        in the web.config found in the root of the identityserver set stdoutLogEnabled=”true”

      • 15/05/2019 at 20:27

        it goes it to the production folder.
        can you see this in message in the log “Adding ADFS clientId…….”
        in the web.config found in the root of the identityserver set stdoutLogEnabled=”true”

  4. Corey Burnett
    15/05/2019 at 20:37

    Also can you give an example of what an AuthorityAddress and a MetaAddress might look like? Are these URLs to the ADFS server?

    • 15/05/2019 at 20:41

      I’ve updated with better image also note I’ve removed the “PT.” part so it matches from code from github I’ve just validated against a clean sitecore install, so please try that.

      Authority could be something like https://adfs.yourdomain.com/adfs
      MetaAdress could be https://adfs.yourdomain.com/FederationMetadata/2007-06/FederationMetadata.xml

    • 15/05/2019 at 20:41

      please let me know if that enables the button.

      • Corey Burnett
        15/05/2019 at 20:43

        Ok. At the moment I do not have ADFS set up yet. I just wanted to get the Sitecore stuff set up first. Will the AD button show up if I put in a dummy address for Authority and MetaAddress? Or will it fail without the correct addresses?

      • 15/05/2019 at 21:02

        No I’ve just tested with filling in the text “dummy” can you show how you placed everything in your runtimefolder ? and the content of the manifest files for the module ?

      • 15/05/2019 at 22:04

        Let me know if you manage to get the button, please verify the correct names for folders and files placed in the runtime folder

  5. Corey Burnett
    16/05/2019 at 15:03

    Here’s what I don’t get. How does Sitecore know to use the new stuff that we added to Identity Server? When I look at this file – App_Config/Sitecore/Owin.Authentication.IdentityServer/Sitecore.Owin.Authentication.IdentityServer.config I see an IdentityProviders node. In there is an IdentityProvider that has an id of SitecoreIdentityServer. It has a node called “caption” that says “Go to login”. This is what controls the text of the button. So it seems like Sitecore is using this config file to figure out how to set up the button on the login screen and where that button should go. Unless I am misunderstanding how this works.

    • 16/05/2019 at 15:07

      Did you og Through the installation using sif and is there a hostname present in confit files that points to that site. You can verify it by looking in the iis manager to se if you have a identity server site and after that verify it has a valid ssl certificate that is trusted !

      • Corey Burnett
        16/05/2019 at 15:19

        This instance was an upgrade from 9.0 to 9.1. I followed the guide and installed IdentityServer using SIF. I do have an IdentityServer site in IIS. How do I verify that it has a valid SSL cert that is trusted?

      • 16/05/2019 at 15:28

        I don’t know with the upgrade but I’m pretty sure you can find a guide on the Sitecore doc site about enabling identity server. With the default install for Sitecore XP it will install an IdentityServer

      • Corey Burnett
        16/05/2019 at 15:32

        I do have an IdentityServer installed. It is up and running.

      • 16/05/2019 at 15:41

        Okay can you see the ad button when you visit the identityserver in a browser

      • Corey Burnett
        16/05/2019 at 15:51

        Should I be able to open up the IdentityServer in a browser? When I try to do that I get an error saying that there is an error on the web.config file and that the config file is invalid. But when I look at it it seems fine.

      • 16/05/2019 at 15:54

        Can you set log output to true and look at the log files ? Remember to restart app pool

      • 16/05/2019 at 16:00

        it should look somethin like this below
        aspNetCore processPath=”dotnet” arguments=”.\Sitecore.IdentityServer.Host.dll” stdoutLogEnabled=”true” stdoutLogFile=”.\logs\stdout”

        I’ve added example configuration files to the github project, files that belongs to runtime folder shown in the picture in blog post

      • Corey Burnett
        16/05/2019 at 16:02

        Yes I set log output to true. I restarted the app pool. Where are the IdentityServer logs supposed to be? Is there a log directory somewhere in the IdentityServer site? Or do the IdentityServer logs show up in the regular Sitecore log folder? According to the IdentityServer config file the logs are supposed to go in “\logs\stdout”. But that folder does not exist in the IdentityServer folder.

      • 16/05/2019 at 16:07

        Strange it should be created during install or when the site starts

      • Corey Burnett
        16/05/2019 at 16:15

        Are you able to open up a browser and go to your IdentityServer? Something like this: http://myIdentityServer. Does that work for you?

      • 16/05/2019 at 16:26

        Yes but remember to use https

      • Corey Burnett
        16/05/2019 at 16:37

        Hmmm – when I try that (with HTTPS) I get a 500.19 internal server error. “The requested page cannot be accessed because the related configuration data for the page is invalid.” Seems to be a problem with my web.config file. Can you add your Identity Server web.config file to GitHub?

      • 16/05/2019 at 16:52

        Try to remove everything from the runtime folder if it still fails something went wrong during installation

      • 16/05/2019 at 17:54

        Anything in the log files ??

      • Corey Burnett
        16/05/2019 at 18:01

        No. There isn’t even a logs directory created.

      • 16/05/2019 at 18:46

        Strange never experienced that before.

      • 16/05/2019 at 21:18

        Have verified all prerequisite are ok for the installation .net core and so on is installed

      • Corey Burnett
        16/05/2019 at 22:56

        Figured out part of my problem. I didn’t have the ASP.NET Core hosting bundle installed. The Sitecore documentation just said I need the .NET Core Runtime. In reality I need the full hosting module. Otherwise I can’t run a .NET Core site in IIS. So that is working now. I can browse to my Identity Server site. And it created the Logs folder and I am getting log file created now! But I still don’t see the “AD” button. Instead I see a button that says “Go to login”. Where is the text for the button defined?

      • 16/05/2019 at 22:58

        The go to login is on the Sitecore cm server not the identityserver so be sure you’re on the correct url ie the identityserver

      • Corey Burnett
        16/05/2019 at 23:12

        Ok. Maybe I am confused. How do I sign in to Sitecore with Identity Server? First I go to my browser and enter http://mysitecorecm.local/sitecore right? And does it automatically take me to the Identity Server? Am I supposed to see a page on the Identity Server to sign in? This is really really confusing.

      • 16/05/2019 at 23:15

        I have seen cases where I was not correctly redirected to identity server but simply just enter the url in your browser for the identityserver..

      • Corey Burnett
        16/05/2019 at 23:22

        I think I am finally understanding what is going on here. If Identity Server has errors or doesn’t start or something then you get sent to the Sitecore CM login page (which looks identical to the Identity Server login page and has the “Go to login” button). If Identity Server is working properly then I see the Identity Server sign in page. The problem is that they are almost identical. For a long time my Identity Server wasn’t working. But I never got any error or anything. I was just sent to the CM sign in page. So I was fooled in to thinking it was working correctly. But it wasn’t. So I think I am getting close. At the moment I am having problems with my custom DLL that I created using your code. I don’t think the versions of the supporting DLLs match the versions that are in the Identity Server root directory. But I can work on fixing that. Whew. This is complicated.

      • 17/05/2019 at 08:14

        Have you tried using the example configuration from github and what is in the log ? Remember the dLl should also be in runtime folder not the root folder

      • Corey Burnett
        17/05/2019 at 15:22

        Where should my custom DLL be placed? In the sitecoreruntime folder? In the production folder?

      • 17/05/2019 at 15:43

        Production folder

      • Corey Burnett
        17/05/2019 at 16:32

        I finally got it working!! My first problem was that I didn’t have the necessary .NET Core hosting software installed (the Sitecore documentation wasn’t specific enough). My second problem was that I wasn’t putting my custom DLL in the right place. It was hard to tell from the image in this blog post. My third problem was that when I built my custom DLL I used different versions of the referenced Microsoft DLLs than the ones that come with Identity Server. So I had to delete that project and make sure I picked the same versions of everything from Nuget as Identity Server uses. My fourth problem was that I was missing a tag in my config XML file. Once I fixed all of those problems then it worked! Thank you so very much for helping me with this. You don’t know how much I appreciate it!

      • 17/05/2019 at 16:33

        You’re welcome glad you got it to work

  6. Corey Burnett
    05/06/2019 at 21:14

    One more question. What is the endpoint URL that I have to configure in ADFS for my Sitecore instance? I assume that I have to set up something in ADFS to tell it where to go after authentication.

    • 05/06/2019 at 21:16

      If you’re thinking of the cm server that needs to point to your identityserver

      • Corey Burnett
        06/06/2019 at 16:52

        No. I am assuming that somewhere in ADFS I have to tell ADFS where to send the user after a successful login right? Don’t I have to give ADFS a URL to send the user to after they finish logging in? Or does ADFS just know to send the user back to the Identity Server?

      • 06/06/2019 at 16:56

        again are you talking after authentication on the adfs server or identityserver if the you mean the adfs It Will return the user to the identityserver … not need to configure anything there. And the identityserver will have a callback parameter in the url from site or you really should read about this in the is identityserver “standard” documentation

      • Corey Burnett
        06/06/2019 at 17:02

        Ok. Thanks. The reason I am asking is that the client I am working with is asking for a Sitecore URL that they need to enter in to ADFS. I have read all of the documentation but most of it doesn’t make much sense to me since I have no experience with ADFS at all.

      • 06/06/2019 at 17:08

        That shouldn’t be necessary. All authentication communication seen from the adfs server is against/with the identityserver is doesn’t need to know about the Sitecore server

  7. Corey Burnett
    07/06/2019 at 16:04

    I am trying to understand the differences between what you did here and the official Sitecore documentation (https://doc.sitecore.com/developers/91/sitecore-experience-management/en/configure-federated-authentication.html). The Sitecore documentation for how to set up Federated Authentication is very, very different from what you did. The Sitecore doc talks about all kinds of stuff you have to do on the Sitecore CM server. Your approach just drops some stuff in the Identity Server folders. Is there a reason that these approaches are so different?

    • 07/06/2019 at 16:12

      Have you read the documentation from Sitecore on identityserver and the identityserver 4 documentation.
      All I did was configure adfs and plugin The code from this blog on the identityserver.

      • Corey Burnett
        07/06/2019 at 16:19

        Yes I have read all of the Sitecore documentation on Identity Server. None of the Sitecore documentation shows an approach that is at all like yours. The examples show in the Sitecore documentation are very different.

      • 07/06/2019 at 16:36

        Identityserver is isolated, so be sure it is enabled and you can login to Sitecore from it, then you can install this module in the identityserver. The rest is now configurations in the identityserver and setting up adfs, no additional work in Sitecore (only if you want some user naming stuff)

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: