2010-08-06 9 views
6

¿Hay alguna forma de enumerar qué funciones tienen acceso a una página determinada a través del código?¿Cómo puedo enumerar programáticamente qué función de ASP.Net puede acceder a una página?

Ejemplo, tengo una Testpage.aspx, y quería enumerar los roles permitidos para esta página cuando un usuario accede a la página. El URLAuthorizationManager debe ser capaz de descubrir esto de alguna manera, por lo que debe haber una forma de que sepa qué roles se configuran en el webconfig para una página. o URL

Aquí está el webconfig que limita los roles permitidos para ver esta página.

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

Si pudiera encontrar una solución, devolvería "admin", "sales". ¿Alguien sabe cómo puedo hacer esto? Gracias

+0

Podría marcar una de las siguientes respuestas como correctas? –

Respuesta

-1

Use los Roles.GetAllRoles() Método

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

y aquí es un ejemplo en el que la lista de todos los roles: http://weblogs.asp.net/scottgu/archive/2005/10/18/427754.aspx

+3

Esto parece enumerar todos los roles disponibles en la aplicación, no los roles que pueden acceder a la página –

+0

También puede consultar la clase ConfigurationLocation http://msdn.microsoft.com/en-us/library/3dab5d1z .aspx Esta clase se utiliza internamente por lo que es posible que desee seguir excavando con Reflector. –

10

se puede utilizar el siguiente código dentro de la página donde se quiero obtener la información

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

La razón de la llamada a First() es que la configuración de .NET es jerárquica. Suponga que tiene la siguiente jerarquía de sitios web y de configuración:

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

y se llama al código de Test.aspx.cs, entonces la propiedad AuthorizationSection.Rules contiene tres artículos correspondientes respectivamente a la configuración de /SubDir/Web.config, Web.config y machine.config. Entonces, el primer elemento contiene los roles admin y other.

+0

Gracias Ronald. La explicación en su respuesta me indicó la dirección correcta y ahora puedo enumerar todos los roles para una página determinada. – Chris

+1

Es bueno escuchar eso. Si esta fue (parte de) la respuesta a su pregunta, ¿podría marcarla como respondida? Gracias. –

+0

Chris, debe marcar esta respuesta como "Respondida" si le ayudó a resolver la solución. Funcionó para mí también. Gracias Ronald. –

3

Mi problema era muy similar, excepto que necesitaba la capacidad para iterar a través de todos los directorios y subdirectorios relacionados y mostrar las funciones permitidas para cada página web y directorio de la carpeta. No pude usar la solución de Ronald Wildenberg porque estamos usando .Net 2.0, por lo que no tenemos la funcionalidad de Linq.

Su solución me dio la hoja de ruta que necesitaba. También encontré ayuda del Equipo de Soporte IIS Francés de Microsoft, Managing Forms Authentication Programmatically. No quería volver a escribir los archivos de configuración como se publicaron, sino que necesitábamos la capacidad de mostrar los roles permitidos para todos los directorios y páginas en nuestra aplicación. Nuestra aplicación es pequeña. Tiene un total de 15 directorios y menos de 100 páginas, por lo que funciona bastante rápido. Su kilometraje puede variar según el tamaño de su sitio web.

Empecé desde el directorio raíz y busqué recurrentemente todos los webconfigs. Los agregué con su ruta a una lista de cadenas, luego reitero a través de la lista y llamé a mi función ListRoles. Esta función abre la configuración web y obtiene la colección de ubicación. Luego busca el "system.web/authorization" como lo hizo Ronald. Si encuentra una sección de autorización, recorre las reglas y excluye las reglas heredadas y se centra en AuthorizationRuleAction.Permitir a los roles asociados:

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 para la respuesta impresionante. – Teletha

Cuestiones relacionadas