我最近在单个服务器(Windows 2008 R2)上部署了多个 IIS 站点时遇到了这个问题。我们的环境中的每个站点都在不同的应用程序池上运行,但在某些情况下,可以为这些池分配相同的标识。
如果密钥不存在,我们的应用程序会创建一个密钥,并将其放置在一个容器中,该容器的名称基于当前身份。第一个部署的站点始终有效,但如果我们将另一个站点部署到具有相同标识的另一个应用程序池中,第二个站点就会失败。
事实证明,当存储密钥时,Windows 会授予用户“IIS APPPOOL\AppPoolName”的完全访问权限,而不是我们分配给池的身份。
因此,我们的解决方案是为容器提供对当前身份的显式权限(这类似于@Webmixer 的答案,唯一的区别在于CryptoKeyAccessRule
):
CspParameters cspParams;
cspParams = new CspParameters(PROVIDER_RSA_FULL);
cspParams.KeyContainerName = CONTAINER_NAME;
cspParams.Flags = CspProviderFlags.UseMachineKeyStore;
cspParams.ProviderName = "Microsoft Strong Cryptographic Provider";
CryptoKeyAccessRule rule = new CryptoKeyAccessRule(System.Security.Principal.WindowsIdentity.GetCurrent(), CryptoKeyRights.FullControl, AccessControlType.Allow);
cspParams.CryptoKeySecurity = new CryptoKeySecurity();
cspParams.CryptoKeySecurity.SetAccessRule(rule);