Multiplex login CMS 12 and .NET core 5

Vote:
 

We are trying to implement multiplex login in Optimizely CMS 12 with .NET Core 5. We want our users to be able to login with either Azure AD users or Optimizely DB users. We have used this article as a starting point, but this is for .NET framework and Optimizely CMS 11. Below you can see our code for configuring login in Startup.cs. The problem is that when we navigate to /episerver/cms it is only the last login provider that is being checked in the Challenge. In other words, with this code only the AAD-cookie is checked. And if we swap them only the cookie for regular Optimizely login is checked.

 

 From Configuration() method in Startup.cs

 

            //regular Optimizely DB-login

                .AddCmsAspNetIdentity<ApplicationUser>();

            services.AddCmsHost();

            services.ConfigureApplicationCookie(options =>

            {

                options.LoginPath = "/util/Login";

            });

 

            //Ad-login

            services.AddAuthentication(options =>

            {

                options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;

                options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;

            })

            .AddCookie()

            .AddOpenIdConnect(

                options =>

                {

                    options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;

                    options.ClientId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";

                    options.Authority = "https://login.microsoftonline.com/" + "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + "/v2.0";

                    options.CallbackPath = "/signin-oidc";

                    options.Scope.Add("email");

                    options.TokenValidationParameters = new TokenValidationParameters

                    {

                        ValidateIssuer = false,

                        RoleClaimType = ClaimTypes.Role,

                        NameClaimType = ClaimTypes.Email

                    };

                    options.Events.OnAuthenticationFailed = context =>

                    {

                        context.HandleResponse();

                        context.Response.BodyWriter.WriteAsync(Encoding.ASCII.GetBytes(context.Exception.Message));

                        return Task.FromResult(0);

                    };

                    options.Events.OnTokenValidated = (ctx) =>

                    {

                        var redirectUri = new Uri(ctx.Properties.RedirectUri, UriKind.RelativeOrAbsolute);

                        if (redirectUri.IsAbsoluteUri)

                        {

                            ctx.Properties.RedirectUri = redirectUri.PathAndQuery;

                        }

                        ServiceLocator.Current.GetInstance<ISynchronizingUserService>().SynchronizeAsync(ctx.Principal.Identity as ClaimsIdentity);

                        return Task.FromResult(0);

                    };

                }

            );

#279001
Apr 22, 2022 12:06
Vote:
 

This topic might help you to select the correct scheme when authenticating https://docs.developers.optimizely.com/content-cloud/v12.0.0-content-cloud/docs/mixed-mode-authentication

#279071
Apr 23, 2022 13:24
Halvard - Apr 26, 2022 12:06
Thank you for answering. We are able to log in users on our site with both Optimizely users and AD users. The issue is that we want to access edit mode(/episerver/cms) with both these users, but Optimizely only uses one of the schemas for the challenge when trying to access the page. So when logged inn with Optimizely DB user and trying to access /episerver/cms we get redirected to AD login. It depends on the order in which the login schemes are registrered in StartUp.cs. If we switch the order in Startup.cs it will redirect us to Optimizely login page when logged in with AD user.

I guess we need to override Optimizely's challenge for /episerver/cms or somehow make the cookie equal for both logins?
Johan Petersson - Apr 26, 2022 12:23
I assume you get redirected/challenged because the user doesn't have sufficient access rights. Note that the CMS doesn't challenge any specific scheme, it uses the default (challenge) scheme. If you change default scheme, then AD users won't be challenged. You probably need to ask one of the user types to login before they try to access edit mode and also make sure they have sufficient access rights.

If you want to have full control over which scheme is used when, then implement your own version of AuthenticationSchemeProvider. But you still need to decide which scheme should be challenged by default when someone tries to access the CMS, both schemes cannot do that.
Halvard - Apr 26, 2022 13:24
I think this article is describing the process in .NET Framwork: https://hacksbyme.net/2017/05/11/mixed-mode-owin-authentication-for-episerver-editors/
It seems weird to me that this was possible in .NET framework but not i .NET core?
Johan Petersson - Apr 26, 2022 13:58
Did you read the info below the heading 'Create custom login'? He created a custom login page where users can choose how they want to log in. So, same issue.
Halvard - Apr 26, 2022 14:08
It seems to me that he can log on with either one of these providers and still be authenticated in Episerver edit mode. This is what we want to accomplish in .NET core. But as you say, Episerver cannot check both schemes when we navigate to /episerver/cms. So I find it strange that this seems to be working in .NET Framwork, but not .NET Core?
Johan Petersson - Apr 26, 2022 14:15
That's not what I wrote. It cannot challenge two different schemes. But the challenge only happens when the user is anonymous. So, if the user logs in first, just like in the article you linked via a custom login page, then it can work. You can also tell the users to login manually before trying to access the CMS, then you don't need a custom login page.

Did you implement a custom AuthenticationSchemeProvider or added a scheme policy that selects correct authentication scheme based on your needs? In this case you could check which scheme is signed in and then authenticate the first signed in scheme. In the docs https://docs.developers.optimizely.com/content-cloud/v12.0.0-content-cloud/docs/mixed-mode-authentication there is an example showing how to force a specific scheme for '/episerver' .
Halvard - Apr 27, 2022 9:20
The policyScheme did it! Thank you so much :)

.AddPolicyScheme("policy-scheme", null, options =>
{
options.ForwardDefaultSelector = ctx =>
{
if (ctx.Request.Cookies.ContainsKey(".AspNetCore." + IdentityConstants.ApplicationScheme))
{
return IdentityConstants.ApplicationScheme;
}
return OpenIdConnectDefaults.AuthenticationScheme;
};
});
* 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.