Skip to content
Eyedia edited this page Dec 18, 2017 · 18 revisions

Aarbac logo

How to Video

How to Video

Background & Thoughts

Technology solution is vast these days, and there is always at least one solution for every technical problem. A typical application has following layers:

  1. Security Layer (Authentication & Authorization)
  2. User Interface Layer
  3. Business Logic Layer
  4. Data Access Layer
  5. And a RDBMS database

Security layer generally just perform authentication and authorization and developers inject various code in these layers(2, 3 & 4) to satisfy the business needs. To facilitate these roles, permissions, entitlements, generally they implement various HasPermission(), IsInGroup(), etc. type methods with many ifs elses, switches, and other conditions to make sure that user with appropriate rights are performing appropriate operations.

During initial days, everything looks good, but messed up soon when complex business scenarios, exceptions are introduced, more ifs, switches are introduced in those layers, code quality decreases and code volume increases and makes production support & enhancements difficult. Nightmare for new team members!

Solution (or just a try) - "Can we separate out permission related code into a complete new layer? and let these layers (2, 3 & 4) do their regular job and not worried about the permission at all?"


What is aarbac?

An Automated Role Based Access Control .NET framework which can handle...

1. Automated Data Filters & Permissions (Schema Based)

Apply row & column level permissions on your SELECT,INSERT,UPDATE & DELETE queries. For example, a read (or select) operation like the following …

select * from Author

automatically may get converted to...

SELECT Author.AuthorId, Author.Name, Author.ZipCodeId FROM Author inner join [ZipCode] [t9] on [t9].ZipCodeId = [Author].ZipCodeId inner join [City] [t10] on [t10].CityId = [t9].CityId WHERE t10.Name in ('New York','Charlotte')

...assuming user belongs to a role which allows him to see only 3 columns from author table and only allowed to see authors from New York and Charlotte cities.

And an update query like the following...

update Author set Name = 'Eyedia', SSN = '999-99-9999' where AuthorId = 9999

may hit exception like...

- User ‘abc’ does have permission to update table ‘Author’ but does not have permission to update column ‘SSN’

Sample Code

Select:

using (Rbac rbac = new Rbac("essie"))   //<-- you should pass the logged in user name from the context
{
    using (RbacSqlQueryEngine engine = new RbacSqlQueryEngine(rbac, query))
    {
        engine.Execute(); //<-- automatically parse and transform query based on role
        if ((!engine.IsErrored) && (engine.Parser.IsParsed) && (engine.Parser.QueryType == RbacQueryTypes.Select))
            return engine.Table; //<-- if it is select query, the table will be loaded
    }
}

Inserts, updates and deletes

using (Rbac rbac = new Rbac("essie"))   //<-- you should pass the logged in user name from the context
{
    using (SqlQueryParser parser = new SqlQueryParser(rbac))
    {
        parser.Parse(query); //<-- this will throw exception if not permitted                   
        //<-- if you are here, you are goood. Just perform basic insert/update/delete here.
    }
}

How does it work?

  1. Authorized user will have 1 associated role. The role will be 2 information: a. (1) The rbac meta data & (2) the entitlement meta data.
  2. The rbac meta data will be generated by aarbac framework.
  3. A role can then be created based out of the rbac meta data according to the business requirements.
  4. Quick view of 'city_mgr' role from 'Books' sample(full xml):
<?xml version="1.0" encoding="UTF-8"?>
<Rbac>
  <Summary GeneratedOn="11/13/2017 6:13:32 PM" GeneratedBy="TODO" />
  <Tables>
    <Table Id="1605580758" Name="Author" Create="False" Read="True" Update="True" Delete="False">
      <Columns>
        <Column Name="AuthorId" Type="int" Create="False" Read="True" Update="False" />
        <Column Name="Name" Type="varchar" Create="False" Read="True" Update="True" />
        <Column Name="SSN" Type="varchar" Create="False" Read="False" Update="False" />
        <Column Name="ZipCodeId" Type="int" Create="False" Read="True" Update="False" />
      </Columns>
      <Relations>
        <Relation Type="Auto" My="ZipCodeId" With="ZipCode.ZipCodeId" />
      </Relations>
      <Conditions>
        <Condition />
      </Conditions>
      <Parameters>
        <Parameter />
      </Parameters>    
    </Table>
    ...
    ...
    <Table Id="1269579561" Name="City" Create="False" Read="True" Update="False" Delete="False">
      <Columns>
        <Column Name="CityId" Type="int" Create="False" Read="True" Update="False" />
        <Column Name="Name" Type="varchar" Create="False" Read="True" Update="False" />
        <Column Name="Population" Type="numeric" Create="False" Read="True" Update="False" />
        <Column Name="Rank" Type="numeric" Create="False" Read="True" Update="False" />
        <Column Name="Type" Type="varchar" Create="False" Read="True" Update="False" />
        <Column Name="County" Type="varchar" Create="False" Read="True" Update="False" />
        <Column Name="StateId" Type="int" Create="False" Read="True" Update="False" />
      </Columns>
      <Relations>
        <Relation Type="Auto" My="StateId" With="State.StateId" />
      </Relations>
      <Conditions>       
        <Condition Name="FilterCity" Columns="Name" WhereClause="__self__.Name in {CityNames}" />      
      </Conditions>
      <Parameters>        
        <Parameter Name="{CityNames}" Description="{CityNames} with comma separated country codes like this ('New York','Charlotte')" />      
      </Parameters>
    </Table>
    ...
    ...
</Tables>
</Rbac>
  1. The meta data (base role xml) is generated by aarbac by scanning through the application database (in this case the 'Books' database).

  2. Admin will modify the xml by adding conditions on required tables. (TODO: User Interface by calling aarbac APIs)

  3. This particular 'City Manager' role restricts users to see records from few defined cities as per user's parameters. Also if you read the xml properly, you will notice that the role...

    7.1 Does not have permission to read SSN from Author table.
    7.2 Cannot insert record into Author or City tables.
    7.3 Can update name of Author.
    7.4 Cannot delete record from Author.

Note - aarbac comes with 'books' application with few sample roles and queries, feel free to try out.


2. Entitlements of User Interface (Menu, Sub Menu, Screen, Screen Elements)

Every role in aarbac has screen entitlement, you can define entitlements for your applications in following 2 categories:
2.1. Menus - Menu and sub menus within (linked list nodes)
2.2. Screens - Screen and Screen Elements (linked list nodes)

And just set visible and enabled properties on those nodes.

How does entitlements work?

  1. Every role has entitlement associated.
  2. The base entitlement of the application will be defined by the admin. Everything the application provides.
  3. An example of entitlement:
<?xml version="1.0" encoding="utf-8"?>
<RbacEntitlements>
  <RbacEntitlementMenus>
    <RbacEntitlementMenu Name="File" Text="File" Visible="true" Enabled="true">
      <RbacEntitlementMenu Name="New" Text="New" Visible="true" Enabled="true">
        <RbacEntitlementMenu Name="Project" Text="Project" Visible="true" Enabled="true" />
        <RbacEntitlementMenu Name="WebSite" Text="Web Site" Visible="true" Enabled="true" />
        <RbacEntitlementMenu Name="TeamProject" Text="Team Project" Visible="true" Enabled="true" />
        <RbacEntitlementMenu Name="File" Text="File" Visible="true" Enabled="true" />
      </RbacEntitlementMenu>
    </RbacEntitlementMenu>
    <RbacEntitlementMenu Name="Edit" Text="Edit" Visible="true" Enabled="true">
      <RbacEntitlementMenu Name="Undo" Text="Undo" Visible="true" Enabled="true" />
      <RbacEntitlementMenu Name="Redo" Text="Redo" Visible="true" Enabled="true" />
      <RbacEntitlementMenu Name="Advanced" Text="Advanced" Visible="true" Enabled="true">
        <RbacEntitlementMenu Name="Format Document" Text="Format Document" Visible="true" Enabled="true" />
        <RbacEntitlementMenu Name="Format Section" Text="Format Section" Visible="true" Enabled="true" />
        <RbacEntitlementMenu Name="Tabify Selected Lines" Text="Tabify Selected Lines" Visible="true" Enabled="true" />        
      </RbacEntitlementMenu>
    </RbacEntitlementMenu>
  </RbacEntitlementMenus>
  <RbacEntitlementScreens>
    <RbacEntitlementScreen Name="Revenue" Text="Revenue" Visible="true" Enabled="true">
      <RbacEntitlementScreen Name="RevenueBox" Text="RevenueBox" Visible="true" Enabled="true">
        <RbacEntitlementScreen Name="ThisYearsRevenue" Text="ThisYearsRevenue" Visible="true" Enabled="false" />
        <RbacEntitlementScreen Name="LastYearsRevenue" Text="LastYearsRevenue" Visible="true" Enabled="false" />
      </RbacEntitlementScreen>
    </RbacEntitlementScreen>
    <RbacEntitlementScreen Name="Profit" Text="Profit" Visible="true" Enabled="true">
      <RbacEntitlementScreen Name="ProfitBox" Text="ProfitBox" Visible="true" Enabled="true">
        <RbacEntitlementScreen Name="ThisYearsProfit" Text="ThisYearsProfit" Visible="true" Enabled="false" />       
      </RbacEntitlementScreen>
    </RbacEntitlementScreen>
  </RbacEntitlementScreens>
</RbacEntitlements>
  1. As you understand the structure is simple linked list of menu & screen nodes. Element within the screen, e.g. 'profitbox' is widget on 'Profit' screen.
  2. Developers will need to code to apply this entitlement when user logs in and when a screen is activated.

Prerequisites:

  1. Microsoft SQL Server.
  2. .NET 4.5.2+

Disclaimer

11/20/2017 - I am new to github and nuget, currently working on nuget release & other basic documentation on github. This document may get updated frequently. aarbac release 1.0.8 is stable, but future release may have some minor changes. PLease execuse me for that. I will remove this disclaimer once everything is stable.