London Dev Meetup Rescheduled! Due to unavoidable reasons, the event has been moved to 21st May. Speakers remain the same—any changes will be communicated. Seats are limited—register here to secure your spot!

Loading...
Area: Optimizely CMS
ARCHIVED This content is retired and no longer maintained. See the latest version here.

A common use case for mixed-mode authentication is having ADFS for your back-end users and another authentication provider for website users. Configuring mixed-mode authentication for the Episerver platform requires the following nuget packages as dependencies

  • Microsoft.Owin.Security.Cookies
  • Microsoft.Owin.Host.SystemWeb
  • Microsoft.Owin.Security.WsFederation

To configure mixed mode OWIN authentication, set the authentication type in the system.web section of the web.config.

XML
<authentication mode="None"></authentication>

To configure mixed mode authentication, also create a Startup file in your project that will handle the configuration of the different authentication middleware.

C#
using System;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.Google;
using Owin;
using WebApplication1.Models;

namespace WebApplication1
{
    public partial class Startup
    {
		    const string LogoutUrl = "/util/logout.aspx";
				
        // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
        public void ConfigureAuth(IAppBuilder app)
        {
            //This will configure cookie authentication at the following urls.  In those pages you are responsible for authentication and calling the OwinContext.Authentication.SignIn method to properly sign in the user
            // and  OwinContext.Authentication.SignOut to logout a user
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
		            AuthenticationType = "Application",
		            LoginPath = new PathString("/Login"),
		            LogoutPath = new PathString("/Logout")
            });

            //This will set ADFS as the default authentication provider 
            app.SetDefaultSignInAsAuthenticationType(WsFederationAuthenticationDefaults.AuthenticationType);
            app.UseCookieAuthentication(new CookieAuthenticationOptions
           {
		           AuthenticationType = WsFederationAuthenticationDefaults.AuthenticationType
           });
            //Enable federated authentication
            app.UseWsFederationAuthentication(new WsFederationAuthenticationOptions()
            {
                //Trusted URL to federation server meta data
                MetadataAddress = "https://devdc.dev.test/federationmetadata/2007-06/federationmetadata.xml",
                //Value of Wtreal must *exactly* match what is configured in the federation server
                Wtrealm = "https://localhost:44303/",
                Notifications = new WsFederationAuthenticationNotifications()
                {
                    RedirectToIdentityProvider = (ctx) =>
                        {
                            //To avoid a redirect loop to the federation server send 403 when user is authenticated but does not have access
                            if (ctx.OwinContext.Response.StatusCode == 401 && ctx.OwinContext.Authentication.User.Identity.IsAuthenticated)
                            {
                                ctx.OwinContext.Response.StatusCode = 403;
                                ctx.HandleResponse();
                            }
                            return Task.FromResult(0);
                        },
                    SecurityTokenValidated = (ctx) =>
                        {
                            //Ignore scheme/host name in redirect Uri to make sure a redirect to HTTPS does not redirect back to HTTP
                            var redirectUri = new Uri(ctx.AuthenticationTicket.Properties.RedirectUri, UriKind.RelativeOrAbsolute);
                            if (redirectUri.IsAbsoluteUri)
                            {
                                ctx.AuthenticationTicket.Properties.RedirectUri = redirectUri.PathAndQuery;
                            }
                            //Sync user and the roles to EPiServer in the background
                            ServiceLocator.Current.GetInstance().SynchronizeAsync(ctx.AuthenticationTicket.Identity);
                            return Task.FromResult(0);
                        }
                }
            });
            //Add stage marker to make sure WsFederation runs on Authenticate (before URL Authorization and virtual roles)
            app.UseStageMarker(PipelineStage.Authenticate);

            //Remap logout to a federated logout
            app.Map(LogoutUrl, map =>
            {
                map.Run(ctx =>
                {
                    ctx.Authentication.SignOut();
                    return Task.FromResult(0);
                });
            });

            //Tell antiforgery to use the name claim
            AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.Name;
        }
    }
}

Related topic

Last updated: Sep 21, 2015