如何以编程方式列出哪个ASP.Net角色可以访问页面?

时间:2021-02-27 07:15:53

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.

例如,我有一个Testpage.aspx,我想在用户访问页面时列出该页面允许的角色。 URLAuthorizationManager必须能够以某种方式找到它,因此必须有一种方法它知道在webconfig中为页面配置了哪些角色。或URL。

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

以下是限制允许查看此页面的角色的webconfig。

<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

如果我能找到解决方案,它将返回“admin”,“sales”。谁知道我怎么做到这一点?谢谢

3 个解决方案

#1


10  

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:

调用First()的原因是.NET配置是分层的。假设您具有以下网站层次结构和配置:

/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.

并且从Test.aspx.cs调用上面的代码,然后属性AuthorizationSection.Rules包含三个项目,分别对应于/SubDir/Web.config,Web.config和machine.config中的配置。所以第一个元素包含admin和其他角色。

#2


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.

我的问题非常相似,除了我需要能够遍历所有目录和相关子目录并显示每个网页和文件夹目录的允许角色。我无法使用Ronald Wildenberg的解决方案,因为我们使用的是.Net 2.0,因此我们没有Linq功能。

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.

他的解决方案给了我我需要的路线图。我还从Microsoft的法语IIS支持团队,以编程方式管理表单身份验证中获得了帮助。我不想像他们发布的那样重写配置文件,而是我们需要能够在我们的应用程序中显示所有目录和页面的允许角色。我们的应用很小。它总共有15个目录,不到100页,因此运行速度非常快。您的里程数取决于您网站的大小。

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:

我从根目录开始,递归搜索所有webconfigs。我将它们的路径添加到字符串列表中然后遍历列表并调用我的ListRoles函数。此功能打开Web配置并获取位置集合。然后它会像Ronald那样寻找“system.web / authorization”。如果它找到一个授权部分,它会遍历规则并排除任何继承的规则,并关注AuthorizationRuleAction.Allow以及相关的角色:

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

来自法国IIS支持团队博客

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

#3


-1  

Use the Roles.GetAllRoles() method

使用Roles.GetAllRoles()方法

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

以下是他们列出所有角色的示例:http://weblogs.asp.net/scottgu/archive/2005/10/18/427754.aspx

#1


10  

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:

调用First()的原因是.NET配置是分层的。假设您具有以下网站层次结构和配置:

/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.

并且从Test.aspx.cs调用上面的代码,然后属性AuthorizationSection.Rules包含三个项目,分别对应于/SubDir/Web.config,Web.config和machine.config中的配置。所以第一个元素包含admin和其他角色。

#2


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.

我的问题非常相似,除了我需要能够遍历所有目录和相关子目录并显示每个网页和文件夹目录的允许角色。我无法使用Ronald Wildenberg的解决方案,因为我们使用的是.Net 2.0,因此我们没有Linq功能。

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.

他的解决方案给了我我需要的路线图。我还从Microsoft的法语IIS支持团队,以编程方式管理表单身份验证中获得了帮助。我不想像他们发布的那样重写配置文件,而是我们需要能够在我们的应用程序中显示所有目录和页面的允许角色。我们的应用很小。它总共有15个目录,不到100页,因此运行速度非常快。您的里程数取决于您网站的大小。

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:

我从根目录开始,递归搜索所有webconfigs。我将它们的路径添加到字符串列表中然后遍历列表并调用我的ListRoles函数。此功能打开Web配置并获取位置集合。然后它会像Ronald那样寻找“system.web / authorization”。如果它找到一个授权部分,它会遍历规则并排除任何继承的规则,并关注AuthorizationRuleAction.Allow以及相关的角色:

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

来自法国IIS支持团队博客

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

#3


-1  

Use the Roles.GetAllRoles() method

使用Roles.GetAllRoles()方法

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

以下是他们列出所有角色的示例:http://weblogs.asp.net/scottgu/archive/2005/10/18/427754.aspx