Five New Optimizely Certifications are Here! Validate your expertise and advance your career with our latest certification exams. Click here to find out more

Migrating ADFS login to Optimizely 12

ZZ
ZZ
Vote:
 

Hi, 

   We are in process of migrating to Optimizely 12 (.NET 6). In this connection I am having some issue migrating ADFS and to make it work as default authentication for Optimizely admin site login

I have followed this guideline from Optimizely -> https://docs.developers.optimizely.com/content-cloud/v12.0.0-content-cloud/docs/mixed-mode-authentication and also Microsoft recommendations on this area

https://learn.microsoft.com/en-us/aspnet/core/security/authentication/ws-federation?view=aspnetcore-6.0

Code from Startup.cs class

public void ConfigureServices(IServiceCollection services)
        {
            Log.Logger = new LoggerConfiguration()
                .Enrich.WithEnvironmentName()
                .Enrich.FromLogContext()
                .Enrich.WithExceptionDetails()
        .ReadFrom.Configuration(_configuration)
        .CreateLogger();
            services.Configure<FindOptions>(options =>
            {
                options.DefaultIndex = "xxx";
                options.ServiceUrl = "xxxxx";
            });
            services.AddAuthentication(options =>
            {
                options.DefaultScheme = "policy-scheme";
                options.DefaultChallengeScheme = " policy-scheme";
            })
             .AddCookie("a-scheme")

             .AddCookie(WsFederationAuthenticationDefaults.CookieName, options =>
             {
                 options.Events.OnSignedIn = async ctx =>
                 {
                     if (ctx.Principal?.Identity is ClaimsIdentity claimsIdentity)
                     {
                         // Syncs user and roles so they are available to the CMS
                         var synchronizingUserService = ctx
                             .HttpContext
                             .RequestServices
                             .GetRequiredService<ISynchronizingUserService>();

                         await synchronizingUserService.SynchronizeAsync(claimsIdentity);
                     }
                 };
             })
             .AddWsFederation(options =>
    {
        options.MetadataAddress = _configuration.GetValue<string>("MetaDataAddress");
        options.Wtrealm = _configuration.GetValue<string>("RelyPartyUri");
        options.SignInScheme = WsFederationAuthenticationDefaults.CookieName;
        options.SignOutScheme = WsFederationAuthenticationDefaults.CookieName;

        //options.TokenValidationParameters = new TokenValidationParameters
        //{
        //    RoleClaimType = ClaimTypes.Role,
        //    NameClaimType = "preferred_username",
        //    ValidateIssuer = false
        //};

        options.Events.OnRedirectToIdentityProvider = ctx =>
        {
            // Prevent redirect loop
            if (ctx.Response.StatusCode == 401)
            {
                ctx.HandleResponse();
            }

            return Task.CompletedTask;
        };

        options.Events.OnAuthenticationFailed = context =>
        {
            context.HandleResponse();
            context.Response.BodyWriter.WriteAsync(Encoding.ASCII.GetBytes(context.Exception.Message));
            return Task.CompletedTask;
        };
        })
             .AddPolicyScheme("policy-scheme", null, options =>
    {
        options.ForwardDefaultSelector = ctx =>
        {
            if (ctx.Request.Path.StartsWithSegments("/util/login", StringComparison.OrdinalIgnoreCase))
            {
                return WsFederationDefaults.AuthenticationScheme;

            }
            return "a-scheme";
        };
    });

            services.AddCms();
            services.AddFind();
            //services.AddCmsAspNetIdentity<ApplicationUser>();
            //services.AddAdminUserRegistration();
            //https://github.com/advanced-cms/time-property
            services.AddTimeProperty();
            services.AddRazorPages().AddRazorRuntimeCompilation();

            services.AddHttpContextAccessor();
            services.AddControllersWithViews();
            // Newtonsoft.Json is added for compatibility reasons
            // The recommended approach is to use System.Text.Json for serialization
            // Visit the following link for more guidance about moving away from Newtonsoft.Json to System.Text.Json
            // https://docs.microsoft.com/dotnet/standard/serialization/system-text-json-migrate-from-newtonsoft-how-to
            //.AddNewtonsoftJson(options =>
            //{
            //    options.UseMemberCasing();
            //});
            services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
            services.AddScoped(x =>
            {
                var actionContext = x.GetRequiredService<IActionContextAccessor>().ActionContext;
                var factory = x.GetRequiredService<IUrlHelperFactory>();
                return factory.GetUrlHelper(actionContext);
            });
            services.AddHttpClient();
        }

When I go to -> https://localhost:5001/util/login?ReturnUrl=%2fepiserver it just shows the normal login page and not our ADFS login page.

Any help would be appreciated

#292180
Edited, Nov 24, 2022 19:14
Vote:
 

For your WS-Fed scheme to actually trigger a login flow, something need to do  challenge for that scheme. E.g. a 401 response. /util/login won't do that, since that view allows anonymous requests.

Why have you onfigured with a policy scheme? Do you intend to support multiple authentication schemes, i.e. "mixed mode"?

What happens if you configure default scheme and default challenge scheme to WsFederationAuthenticationDefaults.CookieName? Then try to access /episerver/cms. Does the correct login flow happen?

#292182
Nov 24, 2022 21:28
* 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.