2

我正在用子项目在 ASP.NET MVC 4 中实现一个应用程序,我希望这些应用程序共享相同的登录名(只需登录一个应用程序,无需登录子项目)。

使用 webForms,我们通常使用机器键来完成,但在 MVC 4 中它不再起作用了。在 MVC 4 中有什么新的解决方案吗?

4

1 回答 1

0

由于这Forms authentication是通过 Forms 身份验证完成的ticket,如果所有应用程序共享一个身份验证票证,则用户只需登录一次,即单点登录。假设我们有两个具有这些 URL 的应用程序:

http://public.mysite.com/app1/default1.aspx
http://public.mysite.com/app2/default2.aspx

如您所见,它们基本上是同一子域下的两个虚拟目录 - app1public.mysite.com.写入的 cookie将对app2可见,反之亦然。

但是,这并不意味着当用户登录app1 时,他会自动登录app2。原因是默认情况下,每个 ASP.NET 应用程序都使用自己的加密密钥来创建 Forms 身份验证票证和 cookie。因此,app1 写入的 cookie 无法被app2成功读取,即使它对app2可见。

我们如何才能让两个应用程序识别对方的身份验证票和cookie?

事实上,它在 ASP.NET 中非常简单。唯一需要做的是更改 web.config 文件元素中的设置。以下是 machinKey 的默认设置:

<machineKey 
validationKey="AutoGenerate,IsolateApps" 
decryptionKey="AutoGenerate,IsolateApps" 
validation="SHA1" 
decryption="Auto" 
/>

通过这些设置,.NET 框架使用自动生成的validationKeydecrytionKey创建身份验证票证和 cookie。每个应用程序使用不同的密钥。为了使多个应用程序共享相同的身份验证票证和 cookie,我们只需将所有应用程序中的validationKeyand设置decrytionKey为相同的值。

为了生成密钥,使用RNGCryptoSErviceProvider了命名空间中的类System.Security.Cryptography,如以下代码示例所示:

 public String CreateKey(int numBytes)
 {
 RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
 byte[] buff = new byte[numBytes];
 rng.GetBytes(buff);
 return BytesToHexString(buff);
 }

 private String BytesToHexString(byte[] bytes)
 {
 StringBuilder hexString = new StringBuilder(64);
 for (int counter = 0; counter < bytes.Length; counter++)
 {
     hexString.Append(String.Format("{0:X2}", bytes[counter]));
 }
 return hexString.ToString();
 }
于 2014-04-05T09:44:34.570 回答