Reputation: 155
I'm trying to do something that seems very basic to me, and I can't get it to work. I have a C# web forms web application project with a master page, a default.aspx page, and an Administrators/default.aspx page. The idea is that authenticated users can get to the home page but only members of an administrators group can get to the administrators page.
I have a web.sitemap file with the two pages in it:
<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>
The master page has a SiteMapDataSource control, a SiteMapPath control, and a Menu control for navigating between the two pages, and a LoginName control to show the current user's user name:
<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>
The two pages themselves have nothing significant in them, just empty content controls and no code. The master page has no code, either.
The Administrators folder has a web.config in it to allow only administrators to access the page in that folder:
<configuration>
<system.web>
<authorization>
<allow users="Administrator" />
<allow roles="Administrators" />
<allow roles="BUILTIN\Administrators" />
<deny users="*" />
</authorization>
</system.web>
</configuration>
The site's primary web.config file specifies to use the Windows authentication mode, and it configures the site map provider to enable security trimming, which hides the link to the Administrators page if you're not allowed to go there:
<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>
When I run the web app on my development computer, it works. If I run Visual Studio as a normal user, Windows's wonderful User Access Control "feature" (sic) strips me out of the Administrators group, so I can't get to the Administrators page. If I run Visual Studio as an administrator, then I can get to the Administrators page. So, I know the web app is all set up properly.
Now I try to get the web site to work in Azure. I went to the Azure management portal and created the web site. On the "Configure" page for the web site, I set up authentication / authorization to an Azure active directory, and I picked the directory. I actually have two directories in this Azure subscription, and I'm using the one that I created last, but I'm pretty sure that's not relevant. I configured a virtual application "/WebApplication1" for the actual web app, although I'm pretty sure that's not relevant either. In my active directory, I have a bunch of users and an Administrators group; some users are members of the group and others aren't. I can also see that my web site is registered as an application in the directory. I publish the web app to Azure from Visual Studio, and it redirects me to Microsoft's login page. After I log in, I can see my home page, the user name is correct, and there is no link to the Administrators page because, by default, role management is disabled. So far, so good.
I go to my root web.config file and add a line to enable the role manager and use AspNetWindowsTokenRoleProvider as the default provider:
<configuration>
<system.web>
<!-- ... -->
<roleManager defaultProvider="AspNetWindowsTokenRoleProvider"
enabled="true" />
<!-- ... -->
</system.web>
</configuration>
I can still run the web app on my computer in Visual Studio, but now when I publish it to Azure and try to open the home page, I get this error: "Method is only supported if the user name parameter matches the user name in the current Windows Identity." It has a big long stack trace that starts with System.Web.UI.Page.ProcessRequestMain at the bottom and ends with System.Web.Security.WindowsTokenRoleProvider.GetCurrentWindowsIdentityAndCheckName(String userName) at the top. None of it is my code; every stack frame is System.Web.something. Quite obviously, it's trying to figure out which roles I'm in so it can decide whether or not to show the link to the Administrators page in the menu.
I'M NOT DOING ANYTHING FANCY. As far as I can tell, I'm using the web controls exactly as they are intended to be used; I'm using defaults property values almost everywhere, and I have no custom code. Also, as far as I can tell, I'm using Azure active directory exactly as it is intended to be used. It just doesn't work. User authentication works, but role authorization doesn't. I've been searching the Internet all week, looking for any documentation I can find on authenticating Azure web sites to an Azure active directory or using the WindowsTokenRoleProvider with Azure. I've gone down quite a few rabbit trails, like how to register an application with an Azure active directory, when it turned out to be as simple as going to the Azure web site's configuration page and turning it on. I've seen other people trying to do similar things and getting my same error message, but I haven't found any explanations or solutions. What am I doing wrong? Is what I'm trying to do just not supported?
Upvotes: 2
Views: 1529
Reputation: 15052
The reason this doesn't work is because you are trying to use Windows authentication with Azure Active Directory identities. Windows authentication only works in on-premises environments where Windows Server Active Directory is configured.
The way to make your scenario work is to use the Azure AD graph API to check and see whether the current user is a member of a particular group. You can find some Azure AD samples here:
https://github.com/AzureADSamples/WebApp-GroupClaims-DotNet https://github.com/AzureADSamples/WebApp-RoleClaims-DotNet
The Authentication / Authorization feature of Azure Web Apps does not yet support authorizing roles or groups, so you will need to turn off that feature and implement this yourself using the links above.
Upvotes: 1