Is it possible to tell IIS to treat all old cookies as expired? (CryptographicException)

元气小坏坏 提交于 2019-12-06 14:56:17

问题


We are using WIF authentication, and we have an issue that pops up on occassion where a users cookie gets in a bad state. The exception that gets thrown is:

System.InvalidOperationException: ID1073: A CryptographicException occurred when attempting to decrypt the cookie using the ProtectedData API (see inner exception for details). If you are using IIS 7.5, this could be due to the loadUserProfile setting on the Application Pool being set to false.  ---> System.Security.Cryptography.CryptographicException: Key not valid for use in specified state.

at System.Security.Cryptography.ProtectedData.Unprotect(Byte[] encryptedData, Byte[] optionalEntropy, DataProtectionScope scope)
at System.IdentityModel.ProtectedDataCookieTransform.Decode(Byte[] encoded)
--- End of inner exception stack trace ---
at System.IdentityModel.ProtectedDataCookieTransform.Decode(Byte[] encoded)
at System.IdentityModel.Tokens.SessionSecurityTokenHandler.ApplyTransforms(Byte[] cookie, Boolean outbound)
at System.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(XmlReader reader, SecurityTokenResolver tokenResolver)
at System.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(Byte[] token, SecurityTokenResolver tokenResolver)
at System.IdentityModel.Services.SessionAuthenticationModule.ReadSessionTokenFromCookie(Byte[] sessionCookie)
at System.IdentityModel.Services.SessionAuthenticationModule.TryReadSessionTokenFromCookie(SessionSecurityToken& sessionToken)
at System.IdentityModel.Services.SessionAuthenticationModule.OnAuthenticateRequest(Object sender, EventArgs eventArgs)
at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

A quick fix for this is to clear your cookies or open in another browser or open in private/incognito mode. But ideally we can tell IIS to treat all cookies older than now as expired. This will force re-authentication, and everyone can continue on their merry way. Recycling the app-pool does not help.

Ideas?

EDIT: I can't say for sure, but I think most of the time we see this problem is when we have had to reboot the server.


回答1:


We are using this here

public class CryptographicErrorModule : IHttpModule
{
    /// <summary>
    /// You will need to configure this module in the Web.config file of your
    /// web and register it with IIS before being able to use it. For more information
    /// see the following link: http://go.microsoft.com/?linkid=8101007
    /// </summary>
    #region IHttpModule Members

    public void Dispose()
    {
        //clean-up code here.
    }

    public void Init(HttpApplication context)
    {
        context.Error += ContextOnError;
    }

    private void ContextOnError(object sender, EventArgs eventArgs)
    {
        var context = HttpContext.Current;
        if (context == null)
            return;

        var error = context.Server.GetLastError();
        var cryptoError = error as CryptographicException;

        if (cryptoError == null && error.InnerException is CryptographicException)
            cryptoError = error.InnerException as CryptographicException;

        if (cryptoError == null)
            return;

        if (context.Request.Cookies["CryptoErrorOccured"] != null)
            return;

        context.Response.Cookies.Clear();
        var cookieCount = context.Request.Cookies.Count;
        for (int i = 0; i < cookieCount; ++i)
        {
            var httpCookie = context.Request.Cookies[i];
            if (httpCookie != null)
            {
                var cookieKey = httpCookie.Name;    

                var cookie = new HttpCookie(cookieKey)
                {
                    Expires = DateTime.Now.AddDays(-1), 
                    Value = "",
                    Path = httpCookie.Path,
                    Domain = httpCookie.Domain,
                    Secure = httpCookie.Secure,
                    HttpOnly = httpCookie.HttpOnly
                };

                context.Response.Cookies.Add(cookie);
            }
        }

        var cryptoErrorCookie = new HttpCookie("CryptoErrorOccured", DateTime.UtcNow.ToString("G"))
        {
            Expires = DateTime.Now.AddMinutes(5)
        };

        context.Response.Cookies.Add(cryptoErrorCookie);
        context.Server.ClearError();
    }

    #endregion
}


来源:https://stackoverflow.com/questions/28857128/is-it-possible-to-tell-iis-to-treat-all-old-cookies-as-expired-cryptographicex

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!