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

发布于 2024-12-11 23:49:41 字数 863 浏览 0 评论 0原文

我想要迁移到 Windows Azure 云的现有 Web 应用程序在(后)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 是否仍然是可行的方法。

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

谢谢!

An existing web application I want to migrate to the Windows Azure Cloud authenticates users the following way somewhere in the (post)authenticaterequest event:

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;
}

The CreateGenericPrincipal method looks up roles in a xml file for the claimsidentity and creates a new GenericPrincipal with that roles.
Pages that need authentication just perform

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

This works fine with one webrole instance since there is no big difference to normal IIS hosting. But will it still work with 2, 3 oder 5 instances? The Azure loadbalancer is not "sticky", users could be forwarded to another instance while using the application. Dunno if Thread.CurrentPrincipal is still the way to go.

I use claims-based identity here. The first time an user enters the page, he gets forwarded to a security token service. Until now, this only happens once. It would be annoying if that happens several times when using multiple instances..

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不念旧人 2024-12-18 23:49:41

通常发生的情况是,您仅被转发一次,重定向舞蹈(被动重定向)发生,并且您获得令牌。令牌通常以加密格式缓存在 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 将使用这些声明来构建 ClaimsPrincipal,其中将包含角色等内容以及正常工作的内容(IsInRole、web.config auth 等)。

如果可能,最好让令牌包含角色作为声明。然而,这是一个关于对有意义的上下文的主张的“正常化”的更长的讨论。请记住,您从 IP-STS 获得的声明是用其自己的术语表示的,它们可能对您的应用程序没有任何意义。例如,我可能会收到客户的声明,称他们属于 Adatum\Managers 组。这对我的应用程序来说完全没有意义,所以我通常会将该令牌交换为我的应用程序可以理解的令牌,并在此过程中通过声明映射(即 Adatum\Managers --> MyApplicationAdminRole)转换或规范化声明。 Windows Azure ACS 服务在这里非常适合帮助实现这一点(规范来自不同 IP 的声明)。

我建议阅读 Vittorio 的书来了解这一切,以获取常见模式:

尤金尼奥的笔记:
添加@dunnry 所写的内容,这都是正确的。增强您在依赖方(您的网络应用程序)中设置的声明的正确扩展点是使用ClaimsAuthenticationManager。此类型的文档位于此处。该页面中有指向示例的指针。在该类中,您将从 XML 文件中读取角色并将它们添加到 ClaimsIdentity 中。应用程序的其余部分不会担心声明等(特别是如果您使用像您的案例一样的角色)。 cookie 加密的 RSA 配置解决了负载均衡器问题。

What typically happens is that you are forwarded only once, the redirect dance (passive redirect) happens, and you get a token. The token is typically cached in a cookie in an encrypted format. So, subsequent requests do not do the redirect dance.

The challenge here is that since the cookie is encrypted, all servers in a web farm must have the encryption key to decrypt. Out of box, you will run into issues with WIF because it defaults to DPAPI. This type of encryption is intentionally different per machine. That breaks in the cloud.

What you need to do is upload a service certificate as part of your deployment and change the way the cookie encrypted to something that is webfarm friendly. Here is the magical code:

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);
}

This sets up your security token handler to use RSA Encryption with key material derived from the installed certificate.

There is more detail and information outlined here in this sample application that illustrates the problem and solution:

http://msdn.microsoft.com/en-us/library/ff966481.aspx

Additional Edit:

There is a pipeline in ASP.NET where WIF is configured. It hooks the authentication event and will pull the token from the cookie and build your IPrincipal so that subsequent code will have that in the context. You typically don't build the Principal yourself when using an STS. Instead, if you need to modify the Principal, you plugin to the pipeline in WIF and insert additional claims to the 'role' claim (actually a URI namespace). WIF will then use those claims to build the ClaimsPrincipal that will contain things like Roles and things just work (IsInRole, web.config auth, etc.).

If possible, it is best to have the token contain the roles as claims. This is a much longer discussion however around 'normalization' of claims to meaningful contexts. Remember, the claims you get from a IP-STS is in their own terms and they might not mean anything to your application. For example, I might get a claim from a customer that they are part of Adatum\Managers group. That is completely meaningless to my application, so what I would typically do is exchange that token for one that my app understands and in the process transform or normalize the claims by claim mappings (i.e. Adatum\Managers --> MyApplicationAdminRole). Windows Azure ACS service is very applicable here to help do that (normalize claims from different IPs).

I would recommend reading Vittorio's book on this all to get the common patterns here:

Eugenio's notes:
Adding to what @dunnry wrote, which is all correct. The proper extensibility point to augment your claim set in the Relying Party (your web app) is by using a ClaimsAuthenticationManager. The docs for this type are here. there are pointers to samples in that page. In that class you would read the roles from the XML file and add them to the ClaimsIdentity. The rest of the app would not worry about claims, etc. (especially if you are using roles like in your case). The RSA config for the cookies encryption solves the load balancer issue.

半世晨晓 2024-12-18 23:49:41

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

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>

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

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

Look at my post, I just did the same thing.

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

Basically the claims token needs to be available to any cluster node, so using a certificate on the sessiontokenhandler will prevent a specific node processing the token in a manner specific to an instance.

In the microsoft.identity element in the config, you need to have an element that looks like this.

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

The application pool will also need to get access to this otherwise it won't be able to find the certificate by thumbprint.

The above code will use this certicate when dealing with the token. If you don't have this setup you will get a null reference exception.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文