Windows Azure:多个实例上的web应用程序,身份验证

本文关键字:web 应用程序 身份验证 实例 Azure Windows | 更新日期: 2023-09-27 18:12:25

我想迁移到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文件中查找claimsidentity的角色,并使用该角色创建一个新的GenericPrincipal。需要身份验证的页面只执行

IPrincipal p = Thread.CurrentPrincipal;
p.IsInRole("rolesFromXml");

这在一个webrole实例中工作得很好,因为它与普通的IIS主机没有太大的区别。但它仍然适用于2、3或5个实例吗?Azure负载均衡器不是"粘性的",用户在使用应用程序时可以被转发到另一个实例。不知道是不是Thread。CurrentPrincipal仍然是可行的方法。

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

谢谢!

Windows Azure:多个实例上的web应用程序,身份验证

通常发生的情况是,您只被转发一次,重定向舞蹈(被动重定向)发生,并且您得到一个令牌。令牌通常以加密格式缓存在cookie中。因此,后续请求不执行重定向舞蹈。

这里的挑战是,由于cookie是加密的,网络场中的所有服务器都必须有加密密钥来解密。开箱即用,您将遇到使用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时,通常不会自己构建主体。相反,如果您需要修改主体,您可以将插件插入到WIF中的管道中,并向"角色"声明(实际上是一个URI名称空间)插入额外的声明。然后,WIF将使用这些声明来构建claimprincipal,该声明将包含诸如角色和正常工作的东西(IsInRole, web。配置权限等)。

如果可能,最好让令牌包含作为声明的角色。然而,这是一个围绕有意义的背景下的"正常化"索赔的更长时间的讨论。请记住,您从IP-STS获得的声明有其自身的术语,它们可能对您的应用程序没有任何意义。例如,我可能从客户那里得到他们是Adatum'Managers组的一部分的声明。这对我的应用程序完全没有意义,所以我通常会做的是将令牌交换为我的应用程序理解的令牌,并在过程中通过声明映射转换或规范化声明(即Adatum'Managers -> MyApplicationAdminRole)。Windows Azure ACS服务在这里非常适用,可以帮助实现这一点(规范化来自不同ip的声明)。

我建议阅读Vittorio关于这一切的书,以获得这里的通用模式:

Eugenio笔记:加上@dunnry写的,都是正确的。在依赖方(您的web应用程序)中增加索赔集的适当扩展点是使用ClaimsAuthenticationManager。这种类型的医生在这里。该页中有指向示例的指针。在这个类中,您将从XML文件中读取角色并将它们添加到ClaimsIdentity中。应用程序的其余部分不需要担心索赔等问题(特别是如果你像在你的案例中那样使用角色)。用于cookie加密的RSA配置解决了负载均衡器问题。

看看我的帖子,我也做了同样的事情。

http://therubblecoder.wordpress.com/2011/10/25/wif-and-load-balancing-with-mvc-3/

基本上,声明令牌需要对任何集群节点可用,因此在sessiontokenhandler上使用证书将防止特定节点以特定于实例的方式处理令牌。

在微软。在配置中的标识元素中,你需要有一个像这样的元素。

<serviceCertificate>
  <certificateReference x509FindType="FindByThumbprint"    findValue="****THUMBPRINT*****" storeLocation="LocalMachine"  storeName="My" />
</serviceCertificate>

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

上面的代码在处理令牌时将使用这个证书。如果你没有这样的设置,你会得到一个空引用异常