Part Three- Attributes.  Now that we have a Principal object with rights loaded as the current requests user we can begin assigning security to code by the users rights as well as their role membership.  The objective here was to be able to tag code to require a right and assign that right to a role.  Any user within the role would have the right and be able to execute the code.  We have everything in place to do this, except the Attributes.

Before e dive into Attributes let me recap where we have been; In part one of this series we covered the IPrincipal and right objects needed to secure code by rights under the asp.net membership and roles framework.  In part two we covered the IHttpModule that was required to make the custom RightPrincipal exist in the current request and we talked about a "RightManager".

What is an Attribute?  The short answer is they add meta data to the code that can affect it's behavior.  Here is the code for the RightAttribute. 

  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.Security.Permissions;

  namespace ObjectHelpDesk.Security
  {
      public class RightAttribute : CodeAccessSecurityAttribute
      {
          private String _userName;
          private String _rightName;
          private Boolean _authenticated;

          public RightAttribute(SecurityAction action) : base(action)
          {
              _authenticated = true;
              _userName = String.Empty;
              _rightName = String.Empty;
          }

          public Boolean Authenticated
          {
              get { return _authenticated; }
              set { _authenticated = value; }
          }

          public String RightName
          {
              get { return _rightName; }
              set { _rightName = value; }
          }

          public String UserName
          {
              get { return _userName; }
              set { _userName = value; }
          }

          public override System.Security.IPermission CreatePermission()
          {
              return new RightPermission(this._authenticated, this._userName, this._rightName);
          }
      }
  }

There is not much to the Attribute code.  There is a UserName, RightName and Authenticated properties.  However, the CreatePermission() method returns a RightPermission.  This is what will check the current user to see if they have the needed right.

You can add a RightPermission to any method that you would like to secure.  For example you could add it to a button event handler in the code behind of a web page.  I added two buttons to a default web page in the project and secured them as follows

  public partial class _Default : System.Web.UI.Page  
{
          protected void Page_Load(object sender, EventArgs e)
          {
          }

          [RightAttribute(System.Security.Permissions.SecurityAction.Demand,RightName="SVN Access")]
          protected void Button1_Click(object sender, EventArgs e)
          {
          ...
          }  

          [RightAttribute(System.Security.Permissions.SecurityAction.Demand,RightName="Manager Access")]
          protected void Button2_Click(object sender, EventArgs e)
          {
           ...
          }
  }

This will give us the ability to test everything after we have created the RightPermission.

Before we dive into the RightPermission we need to revisit the RightManager.

  using System;
  using System.Collections.Generic;

  namespace ObjectHelpDesk.Security
  {
      public static class RightManager
      {
          public static List<Right> GetRightsByUserName(string userName)
          {
              List<Right> result = new List<Right>();
              Right someRight = new Right();
              someRight.Id = new Guid();
              someRight.RightName = "SVN Access";

              if (userName.ToLower().StartsWith("j"))
                  result.Add(someRight);
              return result;
          }  

          public static List<Right> GetRightsByRoleName(string roleName)
          {
              List<Right> result = new List<Right>();
              Right someRight = new Right();
              someRight.Id = new Guid();
              someRight.RightName = "SVN Access";

              if (roleName.ToLower()=="developer")
                  result.Add(someRight);
              return result;
          }
      }
  }

Notice we added a GetRightsByRoleName method.  Again it is a simple method and checks the RoleName to see if it equals "developer".   If it does the "SVN Access" right is added to the results.

Finally we can work with the right Permission object....in Part Four - the RightPermission