本文介绍了是否可以告诉IIS将所有旧Cookie视为已过期? (CryptographicException)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在使用WIF身份验证,并且在用户Cookie处于错误状态的情况下,我们会遇到一个问题.引发的异常是:

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)

对此的一种快速解决方案是清除Cookie或在其他浏览器中打开或以私密/隐身模式打开.但是理想情况下,我们可以告诉IIS将所有早于 now 的cookie视为过期.这将强制进行重新身份验证,每个人都可以按照自己的喜好继续进行.回收应用程序池无济于事.

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.

想法?

我不能肯定地说,但是我认为大多数时候我们看到此问题的原因是我们必须重新启动服务器.

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.

推荐答案

我们在这里使用

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
}

这篇关于是否可以告诉IIS将所有旧Cookie视为已过期? (CryptographicException)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-21 08:34