How do I programmatically list which ASP.Net Role can access a page?
Asked Answered
C

3

6

Is there a way of listing which roles have access to a given page via code?

Example, I have a Testpage.aspx, and I wanted to list the roles allowed for this page when a user accesses the page. The URLAuthorizationManager must be able to find this out somehow, so there must be a way it knows what roles are configured in the webconfig for a page. or URL.

Here is the webconfig limiting the roles allowed to view this page.

<location path="Testpage.aspx">
    <system.web>
      <authorization>
        <allow roles ="admin,sales" />
      </authorization>
    </system.web>
  </location>

If I could find a solution, it would return "admin", "sales". Any one know how I can do this? Thanks

Crocus answered 6/8, 2010 at 18:45 Comment(1)
Could you mark one of the answers below as correct?Rattat
R
13

You can use the following code inside the page where you want to obtain the information.

var section = (AuthorizationSection)
    WebConfigurationManager.GetSection("system.web/authorization");
var rules = section.Rules;
var allowedRoles = rules
    .OfType<AuthorizationRule>()
    .Where(r => r.Action == AuthorizationRuleAction.Allow)
    .Select(r => r.Roles).First();

The reason for the call to First() is that .NET configuration is hierarchical. Suppose you have the following web site hierarchy and configuration:

/Default.aspx
/Web.config        (<allow roles="admin,user" />)
/SubDir/
       /Test.aspx
       /Web.config (<allow roles="admin,other" />)

and you call the code above from Test.aspx.cs, then the property AuthorizationSection.Rules contains three items corresponding to respectively the configuration from /SubDir/Web.config, Web.config and machine.config. So the first element contains the roles admin and other.

Rattat answered 6/8, 2010 at 19:46 Comment(3)
Thanks Ronald. The explanation in your answer pointed me in the right direction and now I can enumerate all the roles for a given page.Crocus
Good to hear that. If this was (part of) the answer to your question, could you then mark it as answered? Thanks.Rattat
Chris, you should mark this answer as "Answered" if it helped you solve the solution. It worked for me too. Thanks Ronald.Goldman
R
3

My problem was very similar except I needed the ability to iterate through all of the directories and related subdirectories and display allowed roles for each web page and folder directory. I was unable to use Ronald Wildenberg's solution because we're using .Net 2.0 so we don't have the Linq functionality.

His solution gave me the roadmap I needed. I also found help from from Microsoft's French IIS Support Team, Managing Forms Authentication Programmatically. I didn't want to rewrite the config files like they posted, rather we needed the ability to show the allowed roles for all directories and pages in our application. Our application is small. It has a total of 15 directories and less than 100 pages so this runs pretty quickly. Your mileage my vary depending on the size of your web site.

I started from the root directory and recursively searched for all webconfigs. I added them with their path to a string list then iterated through the list and called my ListRoles function. This function opens the web config and gets the location collection. Then it looks for the "system.web/authorization" like Ronald did. If it finds an authorization section it loops through the rules and excludes any inherited rules and focuses on AuthorizationRuleAction.Allow with associated roles:

using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Web.Configuration;

public void DisplayWebPageRoles()
{
  //First walk the directories and find folders with Web.config files.
  //Start at the root
  DirectoryInfo baseDir = new DirectoryInfo(Server.MapPath("~/"));

  //Do a little recursion to find Web.Configs search directory and subdirs
  List<string> dirs = DirectoriesWithWebConfigFile(baseDir);

  //Replace the folder path separator except for the baseDir    
  for (int i = 0; i < dirs.Count; i++)
  {
    dirs[i] = dirs[i].Replace(
          baseDir.FullName.Replace("\\", "/"), 
            "/" + baseDir.Name + (i > 0 ? "/" : ""));
  } 

  //Now that we have the directories, we open the Web.configs we 
  //found and find allowed roles for locations and web pages.
  for (int i = 0; i < dirs.Count; i++)
  {            
    //Display on page, save to DB, etc...
    ListRoles(dirs[i]);  
  } 
}


public List<string> DirectoriesWithWebConfigFile(DirectoryInfo directory)
{
    List<string> dirs = new List<string>();

    foreach (FileInfo file in directory.GetFiles("Web.config"))
    {
        dirs.Add(directory.FullName.Replace("\\","/"));            
    }
    foreach (DirectoryInfo dir in directory.GetDirectories())
    {
        dirs.AddRange(DirectoriesWithWebConfigFile(dir));
    }
    return dirs;
}

private void ListRoles(string configFilePath)
{        
    System.Configuration.Configuration configuration =
    WebConfigurationManager.OpenWebConfiguration(configFilePath);            

    //Get location entries in web.config file
    ConfigurationLocationCollection locCollection = configuration.Locations;

    string locPath = string.Empty;

    foreach (ConfigurationLocation loc in locCollection)
    {
        try
        {
            Configuration config = loc.OpenConfiguration();
            //Get the location path so we know if the allowed roles are
            //assigned to a folder location or a web page.
            locPath = loc.Path;

            if (locPath.EndsWith(".js")) //Exclude Javascript libraries
            {
                continue;
            }
            AuthorizationSection authSection =
                (AuthorizationSection)config
                               .GetSection("system.web/authorization");

            if (authSection != null)
            {
                foreach (AuthorizationRule ar in authSection.Rules)
                {
                    if (IsRuleInherited(ar))
                    {
                        continue;
                    }

                    if (ar.Action == AuthorizationRuleAction.Allow 
                        && ar.Roles != null 
                        && ar.Roles.Count > 0)
                    {
                        for (int x = 0; x < ar.Roles.Count; x++)
                        {
                            //Display on page, save to DB, etc...
                            //Testing
                            //Response.Write(
                            //   configFilePath + "/web.config" + "," 
                            //   + configFilePath + "/" + locPath + "," 
                            //   + ar.Roles[x] + "<br />");
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
           //Your Error Handling Code...
        }

    }
}

From French IIS support Team blog

private bool IsRuleInherited(AuthorizationRule rule)
{
    //to see if an access rule is inherited from the web.config above
    //the current one in the hierarchy, we look at two PropertyInformation
    //objects - one corresponding to roles and one corresponding to
    //users

    PropertyInformation usersProperty = rule.ElementInformation.Properties["users"];
    PropertyInformation rolesProperty = rule.ElementInformation.Properties["roles"];

    //only one of these properties will be non null. If the property
    //is equal to PropertyValueOrigin.Inherited, the this access rule
    //if not returned in this web.config
    if (usersProperty != null)
    {
        if (usersProperty.ValueOrigin == PropertyValueOrigin.Inherited)
            return true;
    }

    if (rolesProperty != null)
    {
        if (rolesProperty.ValueOrigin == PropertyValueOrigin.Inherited)
            return true;
    }

    return false;
}
Revanche answered 21/2, 2011 at 22:25 Comment(0)
D
-1

Use the Roles.GetAllRoles() method

http://msdn.microsoft.com/en-us/library/system.web.security.roles.getallroles.aspx

and here is an example where they list all roles: http://weblogs.asp.net/scottgu/archive/2005/10/18/427754.aspx

Duck answered 6/8, 2010 at 19:7 Comment(2)
This seems to list all available roles in the application -- not the roles that can access the pageCordierite
You can also take a look at the ConfigurationLocation class msdn.microsoft.com/en-us/library/3dab5d1z.aspx This class is used internally so you might want to keep digging with Reflector.Duck

© 2022 - 2024 — McMap. All rights reserved.