This post will be pretty short and simple but when I starting thinking about putting up this blog, this was the first topic I came up with. The reason is simply that it took me a lot longer to figure out all the details than I had expected it to (and I have direct access to the devs!).
In forms authentication, users and roles are very straight-forward. The Web Admin Tool allows web-admins to create users, create roles, put users in roles, and it's done. But with Windows Authentication, it's a little vague. Sure, we have "users" but what exactly are "Roles"? Well, the anti-climatic answer is pretty much: Roles are "groups" either local or domain.
Lets say we had two users: "User1" and "User2" who are in two groups (and therefore in two roles) "UsersGroup" and "Group1" like so:
And to show the correlation, I'll also include a simple web.sitemap that looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode title="Root Node, Everyone can see it" roles="*">
<siteMapNode title="UsersGroup can see this node" roles="dannych-02\UsersGroup" />
<siteMapNode title="Only Group 1 can see this node" roles="dannych-02\Group1" />
</siteMapNode>
</siteMap>
Here is User1's page:
And here is User2's page:
There is one more little side note. In this example, I didn't put any urls on the siteMap for demonstration purposes. However, putting this into practice takes a little more effort than I've shown. In Forms Authentication, different parts of the site are secured with location tags in web.config. These tags will implicitly filter a site map (so usually roles attributes usually necessary except to expand visibility). With Windows authentication, the security is also dictated by the file authorization. Denied file access can also implicitly filter a site map in addition to the way location tags do it.
Link to source code
This used to confused me too before I finally understood what was happening. First, let me explain what I'm talking about. Let’s say our SiteMap looks like this:
And in home.aspx we have the following:
<asp:SiteMapDataSource runat="server" id="SiteMapDataSource1"
StartingNodeOffset="1" />
<asp:TreeView runat="server" id="TreeView1"
DataSourceID="SiteMapDataSource1" />
Here's the output:
Now, the same code in page4.aspx and in page10.aspx
So what happened? Well, the SiteMapDataSource needs a new root node for the tree because we requested a StartingNodeOffset. In order to determine this new root node, ASP.NET takes the path to the current node and chooses the next node down from the root node as the new root node. From there, ASP.NET can derive a sub tree that the SiteMapDataSource should represent.
But, in the case of home.aspx, we were at the last node in the chain. The exact same thing would happen if we did this:
<asp:SiteMapDataSource runat="server" id="SiteMapDataSource1"
StartingNodeOffset="1" StartFromCurrentNode="true" />.
The result is that ASP.NET did not have enough nodes in the path to get the new root node, so 'Nothing' was returned and no tree gets rendered:

[StartingNodeOffset="5", page10.aspx]

So when would StartingNodeOffset and StartFromCurrentNode="true" ever be useful together? StartingNodeOffset doesn't have to be positive, it can also be a negative number. Using:
<asp:SiteMapDataSource runat="server" id="SiteMapDataSource1"
StartFromCurrentNode="true" StartingNodeOffset="-3" />
will only show the tree from 3 levels above and downward from wherever you are and thus filtering out potentially large amounts of non-relevant data.