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

时间:2010-08-06 18:45:35

标签: asp.net membership roles

是否有办法列出哪些角色可以通过代码访问给定页面?

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

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

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

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

3 个答案:

答案 0 :(得分:10)

您可以在页面中使用以下代码来获取信息。

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();

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

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

您从Test.aspx.cs调用上面的代码,然后属性AuthorizationSection.Rules包含三个项,分别对应/SubDir/Web.config,{{1}的配置}和Web.config。因此,第一个元素包含角色machine.configadmin

答案 1 :(得分:3)

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

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

我从根目录开始并递归搜索所有webconfigs。我将它们的路径添加到字符串列表中然后遍历列表并调用我的ListRoles函数。此功能打开Web配置并获取位置集合。然后它会像罗纳德那样寻找“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

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

答案 2 :(得分:-1)