现在的位置: 首页 > 综合 > 正文

再谈ASP.NET 7 – 跨应用、跨服务器的表单验证

2012年05月26日 ⁄ 综合 ⁄ 共 2259字 ⁄ 字号 评论关闭

 

         很多情况下,我们想要在同一台服务器上两个不同的应用程序共享相同的Forms验证信息,即在一个应用程序通过验证后,其它应用可以共享这个验证状态,从而不用再次登陆,实现一个单点登录的效果

         使用Forms验证下产生的cookie是被加密的,每个程序都会默认生成独立的解密和校验码,所以我们也很难再不同的应用间共享加密的cookie。要想使共享变得可能,我们需要通过配置文件(服务器端)手动指定加密密钥和验证码。

machineKey默认配置如下:

<machineKey decryption="Auto" validation="SHA1"

            decryptionKey="Auto Generate, IsolateApps" validationKey="Auto Generate, IsolateApps"/>

Ø  decryption属性:用于指定Forms验证下cookie的加密算法,取值有AutoAES3DES,默认为Auto (ASP.NET会根据Web服务器的性能选择最佳加密算法)

Ø  validation属性:用于指定对验证cookie进行Hash与加密的算法,可取值为AESMD5SHA13DES

Ø  descryptionKey属性与validationKey属性:分别表示对验证cookie进行加密的密钥与Hash运算的验证码。

另外,上述配置中:

Ø  AutoGenerate:表示ASP.NET将产生随机密钥,并将其存储在LSA(本地独立存储)

Ø  IsolateApps表示将为Web服务器每个应用程序创建唯一的密钥。

 

我们可以重写服务器端Web.config中的设置,将前文默认配置中decryptionKeyvalidationKey两个属性中的IsolateApps去掉即可,即表示该设置不是对每个应用独立的。

小提示:

服务器端web.config的路径:

C:\Windows\Microsoft.NET\Framework(64)\[version]\CONFIG\web.config

 

另一种情况,如果我们想要不同web服务器(如在一个web farm)上的应用程序共享相同的cookie加密。我们需要手动生产decryptionKeyvalidationKey属性值,并使它们在服务器间保持一致。

AES算法需要一个64位的十六进制字符随机序列,SHA1算法使用一个128位的十六进制随机序列,我们可以通过这样的代码来生成所需的随机序列:

string GetKey(int length)

{

    byte[] buffer = new byte[length / 2];

    RNGCryptoServiceProvider provider = new RNGCryptoServiceProvider();

    provider.GetBytes(buffer);

    StringBuilder builder = new StringBuilder(length);

    for (int i = 0; i < buffer.Length; i++)

    {

        builder.Append(string.Format("{0:X2}", buffer[i]));

    }

    return builder.ToString();

}

         如果我们只是想让两台服务器上同一个应用程序共享相同的验证加密信息,我们需要把machineKey的设置放在应用程序自己的web.config中,另外cookie在设计上就不能用作跨域验证,所以无论是一个Web服务器上的不同应用,还是多个服务器上同一应用都要求在同一个域中(即一级域名要相同,如两个应用app1.sample.comapp2.sample.com就是在同一个域中)使用前文介绍的这种方式才有效。

         ASP.NET对跨域的验证共享也提供了一种解决方案 通过查询字符串代替cookie传递验证凭据。我们需要在web.config中进行如下设置以允许应用程序通过查询字符串传递验证凭据,从而实现验证信息的跨域共享。

<authentication mode="Forms">

  <forms enableCrossAppRedirects="true"/>

</authentication>

将原本存储于cookie中的验证信息加入Url的方式也很简单,即传递普通查询字符串的传递方式。

如,我们有一个HyperLink

<asp:HyperLink ID="lnkToOtherDomain" NavigateUrl="http://www.otherdomain.com/secret.aspx"

    runat="server" />

我们使用C#代码为其提添加凭据:

protected void Page_Load(object sender, EventArgs e)

{

    string cookieName = FormsAuthentication.FormsCookieName;

    string cookieValue = FormsAuthentication.GetAuthCookie(User.Identity.Name, false).Value;

    lnkToOtherDomain.NavigateUrl += string.Format("?{0}={1}", cookieName, cookieValue);

}

 

 

抱歉!评论已关闭.