Windows Azure:几个实例上的Web应用程序,身份验证?

时间:2011-10-25 14:09:23

标签: c# .net authentication azure claims-based-identity

我想要迁移到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仍然是要走的路。

我在这里使用基于声明的身份。用户第一次进入页面时,会转发到安全令牌服务。到现在为止,这只发生过一次。如果在使用多个实例时多次发生这种情况会很烦人。

谢谢!

2 个答案:

答案 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>

应用程序池还需要访问它,否则它将无法通过指纹找到证书。

上述代码在处理令牌时将使用此证书。如果您没有此设置,您将获得空引用异常。