I couldn't find a good way to keep a user who logged in from seeing the preview page. With that being said, here's what I ended up doing:
public class RedirectUserToChangedPassword : HttpRequestProcessor
{
private TimeSpan TimeSpanToExpirePassword { get; set; }
private string ChangePasswordPageUrl { get; set; }
public override void Process(HttpRequestArgs args)
{
if (((Sitecore.Context.PageMode.IsNormal || Sitecore.Context.PageMode.IsPreview)
&& Sitecore.Context.Site != null
//custom method: IsContentSite
&& Sitecore.Context.Site.IsContentSite())
|| Sitecore.Context.User == null
|| Sitecore.Context.User.IsAdministrator
|| args.Url == null
|| String.Equals(args.Url.FilePath, ChangePasswordPageUrl, StringComparison.CurrentCultureIgnoreCase))
return;
var membershipUser = Membership.GetUser(Sitecore.Context.User.Name, false);
if (!HasPasswordExpired(membershipUser))
return;
var queryString = new NameValueCollection();
queryString.Add(Constants.Sitecore.ChangePassword.OriginalUrlKey, args.Url.FilePathWithQueryString);
//custom method: ToQueryString
WebUtil.Redirect(ChangePasswordPageUrl + (ChangePasswordPageUrl.Contains("?") ? "&" : "?") + queryString.ToQueryString());
}
private bool HasPasswordExpired(MembershipUser user)
{
return user.LastPasswordChangedDate.Add(TimeSpanToExpirePassword) <= DateTime.Now;
}
}
Patch:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<pipelines>
<httpRequestBegin>
<processor type="MyDll.CustomSitecore.Pipelines.HttpRequest.RedirectUserToChangedPassword, MyDll"
patch:after="*[@type='Sitecore.Pipelines.HttpRequest.UserResolver, Sitecore.Kernel']">
<TimeSpanToExpirePassword>00:00:01:00</TimeSpanToExpirePassword>
<ChangePasswordPageUrl>/sitecore/shell/Applications/Security/ChangePassword/customchangepassword.aspx</ChangePasswordPageUrl>
</processor>
</httpRequestBegin>
</pipelines>
</sitecore>
</configuration>
From the config you can see that I created a custom change password page. I copied the default one into my project with a new name and had it inherit my own source. The reason I had to do this is that normally this aspx opens in a dialog. After hitting the continue button it is, by default, set up to close the top dialog. Here is my class that customchangepassword.aspx
used:
public class ChangePasswordPage : Sitecore.Shell.Applications.Security.ChangePassword.ChangePasswordPage
{
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
ChangePassword.ContinueButtonClick += ChangePassword_ContinueButtonClick;
}
private void ChangePassword_ContinueButtonClick(object sender, EventArgs e)
{
Sitecore.Diagnostics.Assert.ArgumentNotNull(sender, "sender");
Sitecore.Diagnostics.Assert.ArgumentNotNull(e, "e");
var originalUrl = Request.QueryString[Constants.Sitecore.ChangePassword.OriginalUrlKey];
if (!originalUrl.IsNullOrEmpty())
{
WebUtil.Redirect(originalUrl);
}
else if (Sitecore.Context.User != null)
{
WebUtil.Redirect(Sitecore.Context.User.Profile.StartUrl);
}
else
{
WebUtil.RedirectToLoginPage();
}
}
}
I kept the original contents of changepassword.aspx
the same other than the very top line. I changed the top line of changepassword.aspx
to the following:
<%@ Page Language="c#" AutoEventWireup="True" Inherits="Namespace.To.Custom.Code.ChangePasswordPage" MasterPageFile="~/sitecore/shell/DialogPage.Master" CodeBehind="ChangePassword.aspx.cs" %>
Constants.Sitecore.ChangePassword.OriginalUrlKey
was in a constant file and had a value of originalUrl
.