If you ever need a disclaimer page in MVC, there are a few things you need to consider, the first is you should not be able to get to a page without agreeing to the disclaimer and if you have to re-login then you need to be presented with the disclaimer page again.
I’ve opted to use an Attribute, which can be used on a Controller.
[AgreeToDisclaimer] public class Page1Controller : Controller {
This makes things very simple and as easy to use as the Authorise Attribute.
The implementation of the AgreeToDisclaimer inherits the Authorize Attribute, which over rides the AuthorizeCore and HandleUnauthorizedRequest methods
public class AgreeToDisclaimerAttribute : AuthorizeAttribute { protected override bool AuthorizeCore(HttpContextBase httpContext) { if (httpContext == null) throw new ArgumentNullException("httpContext"); if (!this.HasAgreedToDisclaimer(httpContext)) return false; return true; } protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { // Returns HTTP 401 by default filterContext.Result = new RedirectToRouteResult( new RouteValueDictionary { { "action", "index" }, { "controller", "Disclaimer" } }); } private bool HasAgreedToDisclaimer(HttpContextBase current) { return current != null && current.User != null ? (bool)current.User.Disclaimer() : false; } }
You’ll have noticed that I have extended the User object to include Disclaimer, this way when the user session expires or the user logs out the current user is null
As for extending the User object this again is quite simple:
public static class IPrincipalExtension { /// <summary> /// ObjectCache references the objects with WeakReferences for avoiding memory leaks. /// </summary> public static ConditionalWeakTable<object, Dictionary<string, object>> ObjectCache = new ConditionalWeakTable<object, Dictionary<string, object>>(); public static void SetValue<T>(this T obj, string name, object value) where T : class { Dictionary<string, object> properties = ObjectCache.GetOrCreateValue(obj); if (properties.ContainsKey(name)) properties[name] = value; else properties.Add(name, value); } public static T GetValue<T>(this object obj, object name) { Dictionary<string, object> properties; if (ObjectCache.TryGetValue(obj, out properties) && properties.ContainsKey(name.ToString())) return (T)properties[name.ToString()]; else return default(T); } public static object GetValue(this object obj, bool name) { return obj.GetValue<object>(name); } public static bool Disclaimer(this IPrincipal principal) { return principal.GetValue<bool>("Disclaimer"); } public static void SetDisclaimer(this IPrincipal principal, bool value) { principal.SetValue("Disclaimer", value); } }