Don't miss out Virtual Happy Hour today (April 26).

Try our conversational search powered by Generative AI!

Using on-prem Active Directory integration in version 12

Vote:
 

Hi!

In previous versions it was very convenient to use the Active Directory Role Provider integration with the cms, so you could have SSO and restrict access to pages based on Active Directory groups.

Is there any way to achieve a similar behaviour in the .net core based version 12? My scenario is a intranet-like situation with my own AD-server, so using Azure AD is not an option.

thanks!

#285738
Aug 18, 2022 11:06
Vote:
 

I tried configuring the site with "Windows Authentication" and using the concept of "virtual roles" as a possible solution, but only getting "unauthorized" when I load it up. I did this in startup.cs. Anything else I need to do? Or maybe version 12 doesnt support "windows authentication" either.

Changes in startup.cs:

services.AddCms();//.AddCmsAspNetIdentity<ApplicationUser>();
services.AddAuthentication(IISDefaults.AuthenticationScheme);

Changes in laungSettings.json:

 "iisSettings": {
    "windowsAuthentication": true,
    "anonymousAuthentication": false,
    "iisExpress": {
      "applicationUrl": "http://localhost:50108/",
      "sslPort": 44344
    }
  },

Added this to appsettings.json (to make local administrators-users be mapped to the Administrator group)

  "EpiServer": {
    "Cms": {
      "MappedRoles": {
        "Items": {
          "Administrator": {
            "MappedRoles": [ "Administrators" ],
            "ShouldMatchAll": "false"
          }
        }
      }
    }
  }

But sadly it doenst work. Any suggestions? Thanks!

#285797
Aug 19, 2022 8:13
Vote:
 

If the server is on the newtwork you can use this package Microsoft.AspNetCorre.Authentication.Negotiate

https://docs.microsoft.com/en-us/aspnet/core/security/authentication/windowsauth?view=aspnetcore-6.0&tabs=visual-studio

#285807
Aug 19, 2022 16:09
Vote:
 

Yes, thank you. Thats the package Im using. I actually got the "windows authentication" part working, and it logs me in automaticly with a local account in my dev-environment. To make it work I had to "turn off" the normal .net Identity functionality (by leaving out .AddCmsAspNetIdentity<ApplicationUser>()). But only if I first gave "Everyone" access to the site at root-level.

Ideally I would like to log in by windows authentication and then somehow "translate" to an internal user so I can take advantage of the group-settings etc. But for now I have no idea how to do that. So any suggestions would be much appreciated. There must be some solution for using version 12 in an intranet environment with SSO?

#285811
Edited, Aug 19, 2022 17:38
Vote:
 

https://docs.developers.optimizely.com/content-cloud/v12.0.0-content-cloud/docs/mixed-mode-authenticationhttps://docs.developers.optimizely.com/content-cloud/v12.0.0-content-cloud/docs/mixed-mode-authentication

In startup you need to implement the authenticated event when you configure teh Negogiate package to sync the user.  The default secutriy event provider will also include synched users so you can conto

options.Events = new NegotiateEvents()
                {
                    OnAuthenticated = context =>
                    {
                        // Create claims identity to sync, map internal roles to Opti roles here
                        var synchronizingUserService = context
                             .HttpContext
                             .RequestServices
                             .GetRequiredService<ISynchronizingUserService>();

                        await synchronizingUserService.SynchronizeAsync(claimsIdentity);            
                        return Task.CompletedTask;
                    }
                };
               
#285815
Edited, Aug 19, 2022 21:03
Vote:
 

Thanks for your help. Tried like this in startup.cs:

services.AddCms().AddAuthentication(options =>
            {
                options.DefaultScheme = IISDefaults.AuthenticationScheme;
            }).AddNegotiate(options =>
                    options.Events = new NegotiateEvents()
                    {
                        OnAuthenticated = async context =>
                        {
                            // Create claims identity to sync, map internal roles to Opti roles here
                            var claimsIdentity = new ClaimsIdentity(new[]
                            {
                                new Claim(ClaimTypes.Role,"WebAdmins"),
                                new Claim(ClaimTypes.Name,"rickard")
                            }, "ApplicationCookie", ClaimTypes.Name, ClaimTypes.Role);

                            var synchronizingUserService = context
                                .HttpContext
                                .RequestServices
                                .GetRequiredService<ISynchronizingUserService>();

                            await synchronizingUserService.SynchronizeAsync(claimsIdentity);
                        }
                    }
            );

But the OnAuthenticated event doesnt even hit, so no new claims is added to the user :(

#285852
Edited, Aug 20, 2022 13:58
Vote:
 

Yeah I see now in the docs 

Claims transformations
When hosting with IIS, AuthenticateAsync isn't called internally to initialize a user. 
Therefore, an IClaimsTransformation implementation used to transform claims after every authentication isn't activated by default. 
For more information and a code example that activates claims transformations, see Differences between in-process and out-of-process hosting.

These docs go into more details.

https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/iis/in-process-hosting?view=aspnetcore-6.0&viewFallbackFrom=aspnetcore-3.1#differences-between-in-process-and-out-of-process-hosting

Here is an example link to an implementation.

https://docs.microsoft.com/en-us/aspnet/core/security/authentication/claims?view=aspnetcore-6.0

Here is how you register the new class.  We have a implementation as well so you want to add another and not replace.

 services.TryAddEnumerable(Microsoft.Extensions.DependencyInjection.ServiceDescriptor.Singleton<IClaimsTransformation, VirtualRoleClaimsTransformer>());
#285853
Aug 20, 2022 17:46
Vote:
 

Good stuff, thank you! This actually seems to be working the way I want, gonna test it out more on monday to be 100% sure. But in my quick test I can login using windows authentication, then use my own claimstransformer to add 2 more roles (WebAdmins, CmsAdmins), and the user gets acces to the site and cms-admin mode! 

So I ended up with this Startup.cs

//Note that Im not adding .AddCmsAspNetIdentity<ApplicationUser>(). If I do that the "normal" login seems to 
//override the windows authentication. Maybe its possible to use both, but I dont need it in my example

services.AddCms().AddAuthentication(options =>
            {
                options.DefaultScheme = IISDefaults.AuthenticationScheme;
            }).AddNegotiate();

// This line hooks in my ClaimsTransformer class which basicly adds another identity to the principal with some more roles that I want
            services.TryAddEnumerable(ServiceDescriptor.Singleton<IClaimsTransformation, ClaimsTransformer>());

For reference this is my ClaimsTransformer.cs. This is just simply adding two more roles

public class ClaimsTransformer : IClaimsTransformation
    {
        public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
        {
            var claimsIdentity = new ClaimsIdentity();
            claimsIdentity.AddClaim(new Claim(ClaimTypes.Role, "WebAdmins"));
            claimsIdentity.AddClaim(new Claim(ClaimTypes.Role, "CmsAdmins"));

            principal.AddIdentity(claimsIdentity);

            return Task.FromResult(principal);
        }
    }
#285890
Edited, Aug 21, 2022 13:23
Vote:
 

Great, I m assuming since the users are on the network you are doing any additional checks, but you might want to do some additional validation before adding them as Webadmin

#285892
Aug 21, 2022 16:24
Vote:
 

Yes, I will check AD-groups and assign appropriate roles. This was just a quick test where I added 2 roles without checking anything. Thanks for all your help!

#285893
Aug 21, 2022 16:25
Neha - Apr 23, 2024 19:00
Hello,

I am trying to host CMS12 project with windows authentication on IIS and I also have same requirement as mentioned by you. I have modified startup.cs file similarly as mentioned by you, and other changes applicable for windows authentication. My appliaction launches from IIS, but when trying to connect to episerver/cms, windows dialog to enter credentials keep coming, even though I added correct credentials. Was wondering, if you also faced same issue?

Br,
Neha
rhagstrand - Apr 23, 2024 21:10
Have you verified that your claimstransformer class works? If it does and you are adding any groups to the userprincipal that isnt standard optimizely groups, lik CmsAdmins, you need to create those groups in your cms application with the exact same name, and give them appropriate access rights to your applications pages.
rhagstrand - Apr 23, 2024 21:10
Have you verified that your claimstransformer class works? If it does and you are adding any groups to the userprincipal that isnt standard optimizely groups, lik CmsAdmins, you need to create those groups in your cms application with the exact same name, and give them appropriate access rights to your applications pages.
rhagstrand - Apr 23, 2024 21:10
Have you verified that your claimstransformer class works? If it does and you are adding any groups to the userprincipal that isnt standard optimizely groups, lik CmsAdmins, you need to create those groups in your cms application with the exact same name, and give them appropriate access rights to your applications pages.
Neha - Apr 25, 2024 20:12
Seems before checking claimstransfomer class , it is failing. If I run application from localhost I get following error :

An unhandled exception occurred while processing the request.
InvalidOperationException: No authenticationScheme was specified, and there was no DefaultChallengeScheme found. The default schemes can be set using either AddAuthentication(string defaultScheme) or AddAuthentication(Action
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.