We're trying to implement a mixed mode authemtication scenario where CMS Editors/Admins login using Azure AD, but Commerce Customers log in using the Commerce database.
Our Startup.cs for the EPiServer CMS is as follows:
{
public class Startup
{
private const string LogoutUrl = "/util/logout.aspx";
public void Configuration(IAppBuilder app)
{
app.AddCmsAspNetIdentity<SiteUser>(new ApplicationOptions
{
});
//// 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 = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/login"),
LogoutPath = new PathString("/logout"),
Provider = new CookieAuthenticationProvider
{
// Enables the application to validate the security stamp when the user logs in.
// This is a security feature which is used when you change a password or add an external login to your account.
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager<SiteUser>, SiteUser>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentity: (manager, user) => manager.GenerateUserIdentityAsync(user)),
OnApplyRedirect = context => context.Response.Redirect(context.RedirectUri),
OnResponseSignOut = context => context.Response.Redirect(UrlResolver.Current.GetUrl(ContentReference.StartPage))
}
});
// Enable cookie authentication, used to store the claims between requests
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 = ConfigurationManager.AppSettings["MetadataAddress"],
// Value of Wtreal must *exactly* match what is configured in the federation server
Wtrealm = ConfigurationManager.AppSettings["Wtrealm"],
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 = async 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;
}
// Create claims for roles
await ServiceLocator.Current.GetInstance<AzureGraphService>()
.CreateRoleClaimsAsync(ctx.AuthenticationTicket.Identity);
try
{
// Sync user and add the roles to EPiServer in the background
await ServiceLocator.Current.GetInstance<ISynchronizingUserService>()
.SynchronizeAsync(ctx.AuthenticationTicket.Identity);
}
catch (Exception ex)
{
throw new Exception(
"Name Claim Type: "
+ ctx.AuthenticationTicket.Identity.NameClaimType,
ex);
}
}
}
});
// 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.NameIdentifier;
}
}
}
In the CMS site's web.config, we've set the authentication mode to "none" and disabled the membership and rolemanager settings.
This works fine when browsing to /episerver - the user is redirected to the authenticaiton provider and once logged in successfully is redirected to the episerver back-end.
Similarly, if a customer logs in to the site at the /Login page, they are prompted for their username and password and can log in OK.
However, when I click the Commerce Manager link in the back-end, I'm prompted to log in using the standard Commerce Admin login page even though my user is a member of the virtual role Commerce Admins - is this correct?
I assume that for Commerce Customers to log in, the Commerce Manager site needs to retain the SQL Server membership and role provider settings, but is it possible to disable authentication for the Commerce Manager site so we don't need to log in to the Commerce Manager back-end?
If so, do I need to provide the same/similar Startup.cs for the Commerce Manager site?
There seems to be some interaction between the MediaChase assemblies and the login porcess that I need to override, but it's not clear what...
We're trying to implement a mixed mode authemtication scenario where CMS Editors/Admins login using Azure AD, but Commerce Customers log in using the Commerce database.
Our Startup.cs for the EPiServer CMS is as follows:
In the CMS site's web.config, we've set the authentication mode to "none" and disabled the membership and rolemanager settings.
This works fine when browsing to /episerver - the user is redirected to the authenticaiton provider and once logged in successfully is redirected to the episerver back-end.
Similarly, if a customer logs in to the site at the /Login page, they are prompted for their username and password and can log in OK.
However, when I click the Commerce Manager link in the back-end, I'm prompted to log in using the standard Commerce Admin login page even though my user is a member of the virtual role Commerce Admins - is this correct?
I assume that for Commerce Customers to log in, the Commerce Manager site needs to retain the SQL Server membership and role provider settings, but is it possible to disable authentication for the Commerce Manager site so we don't need to log in to the Commerce Manager back-end?
If so, do I need to provide the same/similar Startup.cs for the Commerce Manager site?
There seems to be some interaction between the MediaChase assemblies and the login porcess that I need to override, but it's not clear what...