Как программно указать, какая роль ASP.Net может получить доступ к странице - PullRequest
6 голосов
/ 06 августа 2010

Есть ли способ перечислить, какие роли имеют доступ к данной странице с помощью кода?

Например, у меня есть Testpage.aspx, и я хотел перечислить роли, разрешенные для этой страницы, когда пользователь обращаетсястраница.URLAuthorizationManager должен каким-то образом это выяснить, поэтому должен быть способ узнать, какие роли настроены в веб-конфигурации для страницы.или URL.

Вот веб-конфигурация, ограничивающая роли, разрешенные для просмотра этой страницы.

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

Если бы я мог найти решение, оно вернуло бы «admin», «sales».Кто-нибудь знает, как я могу это сделать?Спасибо

Ответы [ 3 ]

10 голосов
/ 06 августа 2010

Вы можете использовать следующий код на странице, где вы хотите получить информацию.

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 содержит three элементы, соответствующие соответственно конфигурации из /SubDir/Web.config, Web.config и machine.config.Таким образом, первый элемент содержит роли admin и other.

3 голосов
/ 22 февраля 2011

Моя проблема была очень похожей, за исключением того, что мне требовалась возможность перебирать все каталоги и связанные с ними подкаталоги и отображать разрешенные роли для каждой веб-страницы и папки.Я не смог использовать решение Рональда Вильденберга, потому что мы используем .Net 2.0, поэтому у нас нет функциональности Linq.

Его решение дало мне необходимую дорожную карту.Я также получил помощь от французской службы поддержки Microsoft IIS, Программное управление аутентификацией форм .Я не хотел переписывать конфигурационные файлы так, как они были опубликованы, нам нужна была возможность показывать разрешенные роли для всех каталогов и страниц нашего приложения.Наше приложение маленькое.Всего в нем 15 каталогов и менее 100 страниц, поэтому он работает довольно быстро.Ваш пробег может варьироваться в зависимости от размера вашего веб-сайта.

Я начал с корневого каталога и рекурсивно искал все веб-конфигурации.Я добавил их с их путем к списку строк, затем перебрал список и вызвал мою функцию ListRoles.Эта функция открывает веб-конфигурацию и получает коллекцию местоположений.Затем он ищет «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...
        }

    }
}

Из блога группы поддержки французского 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;
}
0 голосов
/ 06 августа 2010

Используйте метод Roles.GetAllRoles ()

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

, и вот пример, в котором перечислены все роли: http://weblogs.asp.net/scottgu/archive/2005/10/18/427754.aspx

...