我想要迁移到Windows Azure云的现有Web应用程序在(post)authenticaterequest事件中的某个位置以下列方式对用户进行身份验证:
IPrincipal current = Thread.CurrentPrincipal;
if (current != null && ((IClaimsIdentity)current.Identity).Claims.Count > 0)
{
IPrincipal result = AuthManager.CreateGenericPrincipal(current.Identity);
HttpContext.Current.User = result;
Thread.CurrentPrincipal = result;
}
CreateGenericPrincipal方法在声明边界的xml文件中查找角色,并创建具有该角色的新GenericPrincipal。 需要身份验证的页面才能执行
IPrincipal p = Thread.CurrentPrincipal;
p.IsInRole("rolesFromXml");
这适用于一个webrole实例,因为与正常的IIS主机没有太大区别。但它仍然适用于2,3或者5个实例吗? Azure负载均衡器不是“粘性”,用户可以在使用应用程序时转发到另一个实例。 Dunno如果Thread.CurrentPrincipal仍然是要走的路。
我在这里使用基于声明的身份。用户第一次进入页面时,会转发到安全令牌服务。到现在为止,这只发生过一次。如果在使用多个实例时多次发生这种情况会很烦人。
谢谢!
答案 0 :(得分:2)
通常情况下,您只会转发一次,重定向舞蹈(被动重定向),并获得令牌。令牌通常以加密格式缓存在cookie中。因此,后续请求不会进行重定向跳舞。
此处的挑战是,由于cookie已加密,因此Web场中的所有服务器都必须具有要解密的加密密钥。开箱即用,您将遇到WIF问题,因为它默认为DPAPI。这种类型的加密是每台机器故意不同的。在云中打破了。
您需要做的是上传服务证书作为部署的一部分,并将cookie加密的方式更改为webfarm友好的方式。这是神奇的代码:
private void OnServiceConfigurationCreated(object sender,
ServiceConfigurationCreatedEventArgs e)
{
var sessionTransforms =
new List<CookieTransform>(
new CookieTransform[]
{
new DeflateCookieTransform(),
new RsaEncryptionCookieTransform(
e.ServiceConfiguration.ServiceCertificate),
new RsaSignatureCookieTransform(
e.ServiceConfiguration.ServiceCertificate)
});
var sessionHandler = new
SessionSecurityTokenHandler(sessionTransforms.AsReadOnly());
e.ServiceConfiguration.SecurityTokenHandlers.AddOrReplace(
sessionHandler);
}
这会将您的安全令牌处理程序设置为使用RSA加密,并使用从已安装的证书派生的密钥材料。
此示例应用程序中提供了更多详细信息和信息,说明了问题和解决方案:
http://msdn.microsoft.com/en-us/library/ff966481.aspx
其他编辑:
ASP.NET中有一个配置WIF的管道。它挂钩了身份验证事件,并将从cookie中提取令牌并构建您的IPrincipal,以便后续代码在上下文中具有该权限。您通常不会在使用STS时自行构建Principal。相反,如果您需要修改Principal,则插入WIF中的管道并将其他声明插入“role”声明(实际上是URI命名空间)。然后,WIF将使用这些声明来构建ClaimsPrincipal,其中包含角色和正常工作的东西(IsInRole,web.config auth等)。
如果可能,最好让令牌包含作为声明的角色。然而,这是一个更长时间的讨论,围绕对有意义背景的主张的“正常化”。请记住,您从IP-STS获得的声明是他们自己的,他们可能对您的应用程序没有任何意义。例如,我可能会从客户处获得他们属于Adatum \ Managers组的声明。这对我的应用程序来说完全没有意义,所以我通常会做的是将该令牌换成我的应用程序理解的那个,并在此过程中通过声明映射转换或规范化声明(即Adatum \ Managers - &gt; MyApplicationAdminRole)。 Windows Azure ACS服务在此非常适用于帮助实现这一点(规范化来自不同IP的声明)。
我建议在这一切上阅读Vittorio's book以获得常见模式:
Eugenio的笔记: 添加到@dunnry所写的内容,这一切都是正确的。适当的可扩展性指向依赖方(您的网络应用程序)中设置的声明集是使用 ClaimsAuthenticationManager 。此类型的文档为here。该页面中有指向样本的指针。在该类中,您将从XML文件中读取角色并将其添加到ClaimsIdentity。应用程序的其余部分不会担心索赔等(特别是如果您使用的是像您的情况一样)。 Cookie加密的RSA配置解决了负载均衡器问题。
答案 1 :(得分:1)
看看我的帖子,我做了同样的事情。
http://therubblecoder.wordpress.com/2011/10/25/wif-and-load-balancing-with-mvc-3/
基本上,声明令牌需要可供任何群集节点使用,因此在sessiontokenhandler上使用证书将阻止特定节点以特定于实例的方式处理令牌。
在配置中的microsoft.identity元素中,您需要有一个看起来像这样的元素。
<serviceCertificate>
<certificateReference x509FindType="FindByThumbprint" findValue="****THUMBPRINT*****" storeLocation="LocalMachine" storeName="My" />
</serviceCertificate>
应用程序池还需要访问它,否则它将无法通过指纹找到证书。
上述代码在处理令牌时将使用此证书。如果您没有此设置,您将获得空引用异常。