2010-08-06 17 views
6

Czy istnieje sposób wpisania, które role mają dostęp do danej strony za pomocą kodu?Jak programowo wyświetlić listę ról ASP.Net, które mogą uzyskać dostęp do strony?

Przykład, mam plik Testpage.aspx i chciałem wyświetlić role dozwolone dla tej strony, gdy użytkownik uzyskuje dostęp do strony. Menedżer URLAuthorizationManager musi być w stanie to jakoś znaleźć, więc musi istnieć sposób, by wiedzieć, jakie role są skonfigurowane w webconfig dla strony. lub URL.

Oto webconfig ograniczający role dozwolone do przeglądania tej strony.

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

Gdybym mógł znaleźć rozwiązanie, zwróciłby "admin", "sales". Czy ktoś wie, jak to zrobić? Dzięki

+0

można zaznaczyć jedną z poniższych odpowiedzi jako prawidłowe? –

Odpowiedz

-1

pomocą Roles.GetAllRoles() metoda

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

i tutaj jest przykładem, gdzie wymienione są wszystkie role: http://weblogs.asp.net/scottgu/archive/2005/10/18/427754.aspx

+3

To wydaje się wylistować wszystkie dostępne role w aplikacji - nie role, które mogą uzyskać dostęp do strony. –

+0

Możesz także rzucić okiem na klasę ConfigurationLocation http://msdn.microsoft.com/en-us/library/3dab5d1z .aspx Ta klasa jest używana wewnętrznie, więc możesz chcieć dalej kopać za pomocą Reflektora. –

10

Można użyć następującego kodu wewnątrz strony, na której chcesz uzyskać informacje.

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

Powodem wywołania First() jest to, że konfiguracja .NET jest hierarchiczna. Załóżmy, że mamy następującą hierarchię stronie internetowej i konfigurację:

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

i wywołać powyższy kod z Test.aspx.cs, właściwość AuthorizationSection.Rules zawiera trzy przedmioty odpowiadające odpowiednio konfiguracja z /SubDir/Web.config, Web.config i machine.config. Zatem pierwszy element zawiera role admin i other.

+0

Dzięki Ronald. Wyjaśnienie w twojej odpowiedzi wskazało mi właściwy kierunek i teraz mogę wyliczyć wszystkie role dla danej strony. – Chris

+1

Dobrze to słyszeć. Jeśli to była (część) odpowiedź na twoje pytanie, czy mogłabyś oznaczyć ją jako odpowiedzą? Dzięki. –

+0

Chris, powinieneś oznaczyć tę odpowiedź jako "odpowiedziano", jeśli pomogła ci rozwiązać rozwiązanie. To działało również dla mnie. Dzięki Ronald. –

3

Mój problem był bardzo podobny, z tym, że potrzebowałem możliwości iterowania wszystkich katalogów i powiązanych podkatalogów oraz wyświetlania dozwolonych ról dla każdej strony internetowej i katalogu folderów. Nie mogłem użyć rozwiązania Ronalda Wildenberga, ponieważ używamy .Net 2.0, więc nie mamy funkcji Linq.

Jego rozwiązanie dało mi mapę drogową, której potrzebowałem. Znalazłem też pomoc od francuskiego zespołu pomocy technicznej IIS firmy Microsoft, Managing Forms Authentication Programmatically. Nie chciałem przepisywać plików konfiguracyjnych tak, jak napisali, potrzebowaliśmy raczej możliwości pokazania dozwolonych ról dla wszystkich katalogów i stron w naszej aplikacji. Nasza aplikacja jest niewielka. Ma w sumie 15 katalogów i mniej niż 100 stron, więc działa dość szybko. Twój przebieg zależy od wielkości Twojej strony internetowej.

Zacząłem od katalogu głównego i rekursywnie wyszukiwałem wszystkie pliki webconfig. Dodałem je z ich ścieżką do listy ciągów, a następnie przejrzałem listę i wywołałem funkcję Moja lista. Ta funkcja otwiera konfigurację internetową i pobiera kolekcję lokalizacji. Następnie szuka "system.web/authorization" jak Ronald. Jeśli znajdzie sekcję autoryzacji, zapętla ona reguły i wyklucza wszelkie odziedziczone reguły i skupia się na AuthorizationRuleAction.Pozostawić związanych z rolami:

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

+1 za wspaniałą odpowiedź. – Teletha