如何让 Azure 网站使用 Azure 活动目录对用户和角色进行身份验证?

How can I get an Azure web site to authenticate users and roles with an Azure active directory?

我正在尝试做一些对我来说非常基本的事情,但我无法让它发挥作用。我有一个 C# web 表单 web 应用程序项目,其中包含一个母版页、一个 default.aspx 页面和一个 Administrators/default.aspx 页面。这个想法是经过身份验证的用户可以访问主页,但只有管理员组的成员才能访问管理员页面。

我有一个 web.sitemap 文件,里面有两页:

<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0">
  <siteMapNode url="~/Default.aspx" title="Home">
    <siteMapNode url="~/Administrators/Default.aspx" title="Administration" />
  </siteMapNode>
</siteMap>

母版页有一个 SiteMapDataSource 控件、一个 SiteMapPath 控件和一个用于在两个页面之间导航的 Menu 控件,以及一个用于显示当前用户的用户名的 LoginName 控件:

<form id="form1" runat="server">
  <asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server"
    ShowStartingNode="False" StartFromCurrentNode="True" />
  <p>
    <asp:LoginName ID="LoginName1" runat="server" />
  </p>
  <div>
    <asp:SiteMapPath ID="SiteMapPath1" runat="server" RenderCurrentNodeAsLink="True">
    </asp:SiteMapPath>
  </div>
  <div>
    <asp:Menu ID="Menu1" runat="server" DataSourceID="SiteMapDataSource1"
      Font-Underline="True" MaximumDynamicDisplayLevels="0" Orientation="Horizontal">
    </asp:Menu>
  </div>
  <div>
    <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
    </asp:ContentPlaceHolder>
  </div>
</form>

这两个页面本身没有任何意义,只有空的内容控件和代码。母版页也没有代码。

Administrators 文件夹中有一个 web.config,只允许管理员访问该文件夹中的页面:

<configuration>
  <system.web>
    <authorization>
      <allow users="Administrator" />
      <allow roles="Administrators" />
      <allow roles="BUILTIN\Administrators" />
      <deny users="*" />
    </authorization>
  </system.web>
</configuration>

站点的主要 web.config 文件指定使用 Windows 身份验证模式,并将站点地图提供程序配置为启用安全修整,这将 link 隐藏到管理员页面如果你不被允许去那里:

<configuration>
  <system.web>
    <authentication mode="Windows" />
    <compilation debug="true"
                 targetFramework="4.6" />
    <customErrors mode="Off" />
    <httpRuntime targetFramework="4.6" />
    <siteMap defaultProvider="XmlSiteMapProvider">
      <providers>
        <add name="XmlSiteMapProvider"
             securityTrimmingEnabled="true"
             siteMapFile="Web.sitemap"
             type="System.Web.XmlSiteMapProvider" />
      </providers>
    </siteMap>
  </system.web>
</configuration>

当我 运行 我的开发计算机上的网络应用程序时,它可以工作。如果我 运行 Visual Studio 作为普通用户,Windows 出色的用户访问控制 "feature" (原文如此)将我从管理员组中删除,所以我无法获得到管理员页面。如果我 运行 Visual Studio 作为管理员,那么我可以进入管理员页面。所以,我知道网络应用程序都已正确设置。

现在我尝试让网站在 Azure 中运行。我转到 Azure 管理门户并创建了网站。在网站的 "Configure" 页面上,我设置了对 Azure 活动目录的身份验证/授权,然后选择了目录。我实际上在这个 Azure 订阅中有两个目录,我正在使用我最后创建的那个,但我很确定这不相关。我为实际的 Web 应用程序配置了一个虚拟应用程序“/WebApplication1”,尽管我很确定这也不相关。在我的活动目录中,我有一堆用户和一个管理员组;一些用户是该组的成员,而另一些则不是。我还可以看到我的网站已注册为目录中的应用程序。我将 Web 应用程序从 Visual Studio 发布到 Azure,它会将我重定向到 Microsoft 的登录页面。登录后,我可以看到我的主页,用户名是正确的,并且没有 link 到 Administrators 页面,因为默认情况下,角色管理是禁用的。到目前为止,还不错。

我转到根 web.config 文件并添加一行以启用角色管理器并使用 AspNetWindowsTokenRoleProvider 作为默认提供程序:

<configuration>
  <system.web>
    <!-- ... -->
    <roleManager defaultProvider="AspNetWindowsTokenRoleProvider"
                 enabled="true" />
    <!-- ... -->
  </system.web>
</configuration>

我仍然可以在 Visual Studio 中 运行 我的计算机上的 Web 应用程序,但现在当我将它发布到 Azure 并尝试打开主页时,我收到此错误:"Method is only supported if the user name parameter matches the user name in the current Windows Identity." 它有一个很长的堆栈跟踪,底部以 System.Web.UI.Page.ProcessRequestMain 开始,顶部以 System.Web.Security.WindowsTokenRoleProvider.GetCurrentWindowsIdentityAndCheckName(String userName) 结束。 None 其中是我的代码;每个堆栈帧都是 System.Web.something。很明显,它试图找出我所处的角色,以便决定是否向菜单中的管理员页面显示 link。

我没有做任何花哨的事情。据我所知,我完全按照预期使用 Web 控件;我几乎在所有地方都使用默认 属性 值,而且我没有自定义代码。此外,据我所知,我使用的 Azure Active Directory 完全按照预期的方式使用。它只是行不通。用户身份验证有效,但角色授权无效。整个星期我都在互联网上搜索,寻找我能找到的关于将 Azure 网站验证到 Azure 活动目录或在 Azure 中使用 WindowsTokenRoleProvider 的任何文档。我已经走了好几条小路,比如如何在 Azure 活动目录中注册应用程序,结果证明它就像转到 Azure 网站的配置页面并打开它一样简单。我见过其他人尝试做类似的事情并收到相同的错误消息,但我没有找到任何解释或解决方案。我究竟做错了什么?我正在尝试做的事情是否不受支持?

这不起作用的原因是您正尝试对 Azure Active Directory 身份使用 Windows 身份验证。 Windows 身份验证仅适用于配置了 Windows 服务器 Active Directory 的本地环境。

使您的方案起作用的方法是使用 Azure AD 图 API 检查并查看当前用户是否是特定组的成员。您可以在此处找到一些 Azure AD 示例:

https://github.com/AzureADSamples/WebApp-GroupClaims-DotNet https://github.com/AzureADSamples/WebApp-RoleClaims-DotNet

A​​zure Web Apps 的身份验证/授权功能尚不支持授权角色或组,因此您需要关闭该功能并使用上面的链接自行实现。