public void OnActionExecuted(ActionExecutedContext filterContext)
        {
            var authenticationManager = filterContext.HttpContext.Get <IAuthenticationManager>();

            var shouldIssueNewCookie = authenticationManager.SignInToken != null;
            var shouldDeleteCookie   = authenticationManager.IsSignOut;

            if (!(shouldIssueNewCookie || shouldDeleteCookie))
            {
                return;
            }

            var cookies = filterContext.HttpContext.Response.Cookies;

            var cookie = new HttpCookie(cookieName)
            {
                HttpOnly = true,
                Path     = "/",
                Secure   = filterContext.HttpContext.Request.IsSecureConnection,
            };

            if (shouldIssueNewCookie)
            {
                cookie.Expires = DateTime.UtcNow.AddYears(20); // effectively never expires
                cookie.Value   = AuthenticationTokenProtector.Protect(authenticationManager.SignInToken);
            }
            else if (shouldDeleteCookie)
            {
                cookie.Expires = expiredCookieDateTime;
            }

            cookies.Add(cookie);

            // set cache headers to not cache the response
            filterContext.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
            filterContext.HttpContext.Response.Cache.SetValidUntilExpires(false);
            filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
            filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
            filterContext.HttpContext.Response.Cache.SetNoStore();
        }
        }                                                                       // no op

        public void OnAuthorization(AuthorizationContext filterContext)
        {
            filterContext.HttpContext.Set <IAuthenticationManager>(new AuthenticationManager());

            var authCookie = filterContext.HttpContext.Request.Cookies.Get(cookieName);

            if (authCookie == null || authCookie.Value.IsNullOrWhiteSpace())
            {
                SetGuestPrincipal(filterContext);
                filterContext.HttpContext.Get <IAuthenticationManager>().SignOut();
                return;
            }

            AuthenticationToken authenticationToken = null;

            try
            {
                authenticationToken = AuthenticationTokenProtector.Unprotect(authCookie.Value);
            }
            catch (Exception)
            {
                System.Diagnostics.Debug.Fail("TODO log and return instead of throwing exception");
                throw;
            }

            // note that we don't check for cookie expiration, we simply don't care.

            var tokenClaim         = authenticationToken.Identity.FindFirst(ClaimTypes.NameIdentifier);
            var authenticationType = authenticationToken.Identity.AuthenticationType;

            UserAccount userAccount = null;

            // TODO move this database access code back behind some provider
            // and implement the switch logic as a subclass instead of procedure
            using (var databaseSession = DatabaseBootstrapper.SessionFactory.OpenSession())
            {
                databaseSession.FlushMode = FlushMode.Commit;
                databaseSession.Transaction.Begin(IsolationLevel.RepeatableRead);
                switch (authenticationType)
                {
                case FacebookAuthentication.AuthenticationType:
                {
                    var id = int.Parse(tokenClaim.Value);
                    userAccount = databaseSession.Get <UserFacebookAccessToken>(id)?.User;
                    break;
                }

                default:
                {
                    System.Diagnostics.Debug.Fail("TODO: log that we have an invalid authentication type");
                    break;
                }
                }
                if (userAccount != null)
                {
                    userAccount.UpdateSeen();
                }
                databaseSession.CommitTransaction();
            }

            if (userAccount == null)
            {
                SetGuestPrincipal(filterContext);
                filterContext.HttpContext.Get <IAuthenticationManager>().SignOut();
            }

            authenticationToken.Identity.RemoveClaim(tokenClaim);
            authenticationToken.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, userAccount.UserAccountId.ToString(), ClaimValueTypes.Integer32));
            authenticationToken.Identity.AddClaim(new Claim(authenticationToken.Identity.NameClaimType, userAccount.Name));
            if (userAccount.IsContributor)
            {
                authenticationToken.Identity.AddClaim(new Claim(authenticationToken.Identity.RoleClaimType, RoleNames.Contributor));
            }
            if (userAccount.IsArchivist)
            {
                authenticationToken.Identity.AddClaim(new Claim(authenticationToken.Identity.RoleClaimType, RoleNames.Archivist));
            }
            if (userAccount.IsAdmin)
            {
                authenticationToken.Identity.AddClaim(new Claim(authenticationToken.Identity.RoleClaimType, RoleNames.Admin));
            }

            SetPrincipal(filterContext.HttpContext, new ClaimsPrincipal(authenticationToken.Identity));
        }