Implementing Custom Users and Roles in .NET Security Framework

Sometime you require using different database of users when authenticating users. This will require you to create custom authentication with customer users and custom roles. In order to implement this you will need to use both System.Security.Principal.IIdentity and System.Security.Principal.IPrincipal interfaces. For instance, WindowsIdentity class is implementation of IIdentity interface as well as FormsIdentity and PassportIdentity.

While implementing IIdentity you must implement following properties. AuthenticationType - description of the authentication mechanism represented as string.

IsAuthenticated – true/false Boolean value which is set to true if authentication OK.

Name - user name represented as string. It must be unique.

class MyCustomIdentity : IIdentity
{
    private bool isMyAuth;
    private string name, authenticationType;
    private string fName, lName;
    public MyCustomIdentity()
    {
        this.name = String.Empty;
        this.isAuthenticated = false;
        this.authenticationType = "None";
        this.firstName = String.Empty;
        this.lastName = String.Empty;
    }

    public MyCustomIdentity(bool isLogin, string newAuthenticationType,
        string newFirstName,
        string newLastName)
    {
        this.name = newfName + newlName;
        this.isAuthenticated = isLogin;
        this.authenticationType = newAuthenticationType;

        this.firstName = newfName;
        this.lastName = newlName;
    }

    public bool IsAuthenticated
    { get { return this.isAuthenticated; } }

    public string Name
    { get { return this.name; } }

    public string AuthenticationType
    { get { return this.authenticationType; } }

    public string lName
    { get { return this.firstName; } }

    public string fName
    { get { return this.lastName; } }
}

While implementing IPrincipal in order to deal with security roles, we need to create one constructor, one method (IsInRole) and one property (Identity). Constructor must accept IIdentity object, list of roles stored as array list.

class CustomPrincipal : IPrincipal
{
      private string[] _myroles;
      private IIdentity _myidentity;

    public CustomPrincipal(IIdentity identity, string[] roles)
    {
        _ myidentity = identity;
        _ myroles = new string[roles.Length];
        roles.CopyTo(_roles, 0);
        Array.Sort(_roles);
    }
    public IIdentity Identity
    { get { return _ myidentity; } }
    public bool IsInRole(string role)
    { return Array.BinarySearch(_myroles, role) >= 0 ? true : false; }
}

If for nay reasons we don’t want use classes based on IIdentity and IPrinciple we can utilize generic System.Security.Principal.GenericIdentity and System.Security.Principal.GenericPrincipal

GenericIdentity myUser001 = new GenericIdentity("Sam");
GenericIdentity myUser002 = new GenericIdentity("Jerry", "SCard");

String[] myUser001Roles = new String[]{"IT", "Users", "Admin"};
GenericPrincipal myPrincipal001 = new GenericPrincipal(myUser001, myUser001Roles);

Implementaiton of our own Identity object and Principle object does not prevent us from using declarative and imperative RBS techniques.