Helper class to dynamically modify the Location configuration element

The location element is used to restrict user or role access on a specific path.The path could be a folder,aspx page,ashx,axd or any other file that is handled by ASP.NET runtime.

In most cases, you use that element declarativley in the web.config file of your website.In this case, you are declaratively telling the ASP.NET runtime and specifically the UrlAuthorizationModule or the FileAuthorizationModule(depending on the Authentication Mode) to grant/deny the access to that path for the specified users/roles.

Sometimes, you will need to allow the administrator to change that using some setting screen and without touching the webiste files, in that case , you will have two options:

  1. If you can live with the application restarts , then you can using the Configuration class to modify location element using the code.I will show you how to do that using my Helper class.
  2. Depending on your site,if you don’t think that it’s ok to restart the application every time you modify the location element using that screen, then you can rollout your custom HttpModule and you could handle one of it’s events like AuthenticateRequest to intercept the incoming request and depending on some database table , you decide if that user is allowd to see that path.

In this post, i will assume that you chose the first option and decided to modify the location element dynamically.

Since i had to do it myself, i decided to create a Helper class that can be used to allow/deny a specific user/role on the given virtualPath.

Class in c#:

  1. public class LocationElementHelper
  2. {
  3.     private Configuration LocationElementConfiguration = null;
  4.     private AuthorizationSection _AuthorizationSection = null;
  5.     private string _configPath = null;
  6.     private string _path = null;
  7.     public LocationElementHelper(string webconfigVirtualPath, string locationElementPath)
  8.     {
  9.         _configPath = webconfigVirtualPath;
  10.         _path = locationElementPath;
  11.         PopulateInternalVariables();
  12.     }
  13.     private void PopulateInternalVariables()
  14.     {
  15.         Configuration config = WebConfigurationManager.OpenWebConfiguration(this._configPath);
  16.  
  17.         if (config.Locations.Count == 0)
  18.             throw new ArgumentException("There is no location element in the specified web.config file");
  19.  
  20.         foreach (ConfigurationLocation loc in config.Locations)
  21.         {
  22.             if (loc.Path.Equals(this._path, StringComparison.InvariantCultureIgnoreCase))
  23.             {
  24.                 LocationElementConfiguration = loc.OpenConfiguration();
  25.  
  26.                 _AuthorizationSection = (AuthorizationSection)LocationElementConfiguration.GetSection("system.web/authorization");
  27.                 if (_AuthorizationSection == null)
  28.                     throw new ArgumentException("Unable to locate the given Location element path in the specified web.config");
  29.  
  30.             }
  31.         }
  32.     }
  33.     public void AddUserToPath(string userName, AuthorizationRuleAction action)
  34.     {
  35.         AuthorizationRule targetRule = null;
  36.         foreach (AuthorizationRule authRule in _AuthorizationSection.Rules)
  37.         {
  38.             if (authRule.Action == action)
  39.             {
  40.                 targetRule = authRule;
  41.                 break;
  42.             }
  43.         }
  44.         // not fund , we add it.
  45.         if (targetRule == null)
  46.         {
  47.             targetRule = new AuthorizationRule(action);
  48.         }
  49.  
  50.         // add  the user
  51.         if (!targetRule.Users.Contains(userName))
  52.             targetRule.Users.Add(userName);
  53.  
  54.         LocationElementConfiguration.Save();
  55.     }
  56.     public void AddRoleToPath(string roleName, AuthorizationRuleAction action)
  57.     {
  58.         AuthorizationRule targetRule = null;
  59.         foreach (AuthorizationRule authRule in _AuthorizationSection.Rules)
  60.         {
  61.             if (authRule.Action == action)
  62.             {
  63.                 targetRule = authRule;
  64.                 break;
  65.             }
  66.         }
  67.         // not found , we add it.
  68.         if (targetRule == null)
  69.         {
  70.             targetRule = new AuthorizationRule(action);
  71.         }
  72.  
  73.         // add the role
  74.         if (!targetRule.Roles.Contains(roleName))
  75.             targetRule.Roles.Add(roleName);
  76.  
  77.         LocationElementConfiguration.Save();
  78.     }
  79.     public void RemoveUserFromPath(string userName, AuthorizationRuleAction action)
  80.     {
  81.         AuthorizationRule targetRule = null;
  82.         foreach (AuthorizationRule authRule in _AuthorizationSection.Rules)
  83.         {
  84.             if (authRule.Action == action)
  85.             {
  86.                 targetRule = authRule;
  87.                 break;
  88.             }
  89.         }
  90.         // not found, we do nothing
  91.         if (targetRule == null)
  92.         {
  93.             return;
  94.         }
  95.  
  96.         // remove the user
  97.         if (targetRule.Users.Contains(userName))
  98.             targetRule.Users.Remove(userName);
  99.  
  100.         // if the Rule has no more users/roles , we remove it.
  101.         if (targetRule.Roles.Count == 0 || targetRule.Users.Count == 0)
  102.             _AuthorizationSection.Rules.Remove(targetRule);
  103.         
  104.         LocationElementConfiguration.Save();
  105.     }
  106.     public void RemoveRoleFromPath(string roleName, AuthorizationRuleAction action)
  107.     {
  108.         AuthorizationRule targetRule = null;
  109.         foreach (AuthorizationRule authRule in _AuthorizationSection.Rules)
  110.         {
  111.             if (authRule.Action == action)
  112.             {
  113.                 targetRule = authRule;
  114.                 break;
  115.             }
  116.         }
  117.         // not found , we do nothing
  118.         if (targetRule == null)
  119.         {
  120.             return;
  121.         }
  122.  
  123.         // remove the role
  124.         if (targetRule.Roles.Contains(roleName))
  125.             targetRule.Roles.Remove(roleName);
  126.  
  127.         // if the Rule has no more users/roles , we remove it.
  128.         if (targetRule.Roles.Count == 0 || targetRule.Users.Count == 0)
  129.             _AuthorizationSection.Rules.Remove(targetRule);
  130.  
  131.         LocationElementConfiguration.Save();
  132.     }
  133. }

Assuming that we have the following location elements in web.config file:

  1. <location path="admin">
  2.   <system.web>
  3.     <authorization>
  4.       <allow users="user1" />
  5.     </authorization>
  6.   </system.web>
  7. </location>
  8. <location path="acct">
  9.   <system.web>
  10.     <authorization>
  11.       <deny users="user1" />
  12.         <allowroles="Accountants"/>
  13.     </authorization>
  14.   </system.web>
  15. </location>

 

To add access to the administrators role on the admin path:

  1. LocationElementHelper helper = new LocationElementHelper("~/", "admin");
  2.   helper.AddRoleToPath("administrators", AuthorizationRuleAction.Allow);

After executing the mentioned code, the admin location will become:

  1. <location path="admin">
  2.   <system.web>
  3.     <authorization>
  4.       <allow users="user1" roles="administrators" />
  5.     </authorization>
  6.   </system.web>
  7. </location>

Another example about removing the <deny users=”user1” /> from the acct.

  1. LocationElementHelper helper = new LocationElementHelper("~/", "acct");
  2.         helper.RemoveUserFromPath("user1", AuthorizationRuleAction.Deny);

 

Hope that helps

Anas


Shout it

2 Comments

Comments have been disabled for this content.