Saturday 13 October 2012

Implementing Role Based Access Control on ACS - Part 1


Role Basic Access Control (RBAC):

Role-based access control is an approach for restricting the system access or activities in system based on group of users who has same role assigned.

Wikipedia says –
“Role-based access control (RBAC) is an approach to restricting system access to authorized users. It is used by the majority of enterprises with more than 500 employees, and can implement mandatory access control (MAC) or discretionary access control (DAC). RBAC is sometimes referred to as role-based security.”

In an organization, roles are created based on the activities of the users, such as Supervisor, Accountant, Manager etc., An user assigned to a particular role will be carried out the activities assigned to that role. It helps the applications deployed on that organization can provide access to that system based on the roles they already possess in that organization.

Important to note here is, the access to the system is depends on the role and not the employee identity (such as employee id or email). So when an employee moves from one role to another, there is only need to change the role of the employee in the central repository store in the identity provider (such as Active Directory or Custom database). Invisibly it will impact the access control system of the systems and restrict the access based on the new role assigned to the user. The same goes when the employee leaves from the organization.

In this post, I am planning to consider using RBAC while implementing Windows Azure ACS in an application.

Setting up the application

Before going for the actual implementation steps, I want to explain my application which needs the RBAC implementation using ACS. The landing page of the application looks as below once the login is successful.
Note: This example POC is just a sample application to show how it works and not a real time example.

As per the application, the users are considered in three roles such as Accountant, Manager, Employee and the other users are fall into guest user. In this application, the Account screen will be accessible by users who are having Accountant role and the Manager screen will be accessible by the users who has Manager Role and so on.

When a user accessing a screen which doesn’t have the access, the user will get the following screen.

The application developed with three aspx pages Accountant.aspx, Employee.aspx and Manager.aspx. Addition to this, I have Default.aspx page added by default. I also have two user control pages ClaimsInfo.ascx which shows the list of user claims and AccessDenied.ascx which shows the access denied message. The user controls will be called from the three pages when required.

Implementation method

To implement RBAC in the application while consuming ACS, the incoming claims must have a Role claim. When using identity provider such as ADFS, it will contain Role claim because that is implemented on top of Active Directory which contains Role in the store. But when using public identity providers such as Live Id, Google Id, Yahoo Id etc., won’t contain Role claim because the public identities have no reason to keep the role of the user as all users are same.

If we required Role claim when using public identities, we can add the Role claim programmatically or from ACS portal itself. Using public identity providers normally not required for enterprise applications, but when developing an application which is targeting to public and the users are categorized by Roles - then we need to add Role claim additionally with the input claims coming from the provider.

For Example: Consider a forum application which required login to Facebook account for doing any operation on that forum. The forum users are categorized by Normal User (who has forum access only), Participant (who has more than a limited access), Reviewer (reviews the post which has conflicts or abuse and approve it) and Administrator (who have admin power) in the forum. In this case, the user will be logged in by Facebook account and the user Role information stored in a separate store in the application.

For implementation of this example, I am planning to use public identity providers such as Google, Live Id, and Yahoo and then planning to use ADFS for logging in. I also plan to decide the Role based on the Email id logged in. (Note: Because of I don’t have multiple Facebook account, I plan to use public identities as below)

For testing I am planning to use three email ids –
Identity ProviderEmail IdRole
Google Idpm.thirumalai@gmail.comAccountant
Live Idpm.thirumalai@live.comManager
Yahoo Idthirumalai_pm@yahoo.co.inEmployee

As we already seen, there are two ways the Role claim can be added while using ACS - one way is from ACS portal or other is using custom code. Initially, I am planning to add Role claim using the ACS portal and then try the same from the custom code.

Creating ACS namespace and configuring Public Identities

Step 1: Create an Access Control Service namespace in the Windows Azure Management Portal. I am creating a namespace as RBACTest as below.

Step 2: Once the namespace is activated, select the namespace and open the Access Control Service portal by selecting the Access Control Service icon from the Manage Access Control tab.
Step 3: Add Public Identities such as Google, Yahoo in the Public Identities. (I am not adding Facebook identity as the email for the Facebook ids are same as Public Identities)
Step 4: Open the Relying Party Application screen and add a relying party as below.
Step 5: Now we need to add Rule Group for the Relying Party Application added in previous step. So navigate to the Rule groups screen and select the Rule of RBAC Test.
Step 6: In the Edit Rule Group screen, click the Generate button.

Step 5: In the Generate Rule screen, select the public identities added and press Generate button.

Now in the Edit Rule Group screen, there will be some rule added. If you look at the list, there won’t be any rule for Role claim as those are public identities.
Step 6: Now go to the Application integration link from the left panel and copy the WS-Federation Metadata.

Configuring the application to use ACS

Step 1: Create a Web Application and add pages as shown as shown in the picture below.
The base application can be downloaded from here.

Step 2: Configure Authentication for the application by right clicking the project and selecting Add STS reference... from the menu. It will open the Federation Utility window.

Step 3: Configure the steps as below screenshots.





Step 4: Make sure the httpRuntime and httpmodules node added in the Web.Config under system.web node.
<httpRuntime requestValidationMode="2.0"/>
<httpModules>
  <add name="WSFederationAuthenticationModule" type="Microsoft.IdentityModel.Web.WSFederationAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
  <add name="SessionAuthenticationModule" type="Microsoft.IdentityModel.Web.SessionAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</httpModules>

Step 5: Run the application and verify the output. The application will re-direct to the list of identity providers screen and when user selects any one of them, it will re-direct to the corresponding login screen of the provider.


Step 6: Open the ClaimsInfo.ascx.cs file and add the below code under Page_Load event.
IClaimsPrincipal claimsPrincipal = Page.User as IClaimsPrincipal;
IClaimsIdentity claimsIdentity = (IClaimsIdentity)claimsPrincipal.Identity;

Table claimsTable = new Table();
claimsTable.CellPadding = 0;
claimsTable.CellSpacing = 0;

TableRow headerRow = new TableRow();
headerRow.BackColor = System.Drawing.Color.LightGray;

TableCell claimTypeCell = new TableCell();
claimTypeCell.Text = "Claim Type";

TableCell claimValueCell = new TableCell();
claimValueCell.Text = "Claim Value";

headerRow.Cells.Add(claimTypeCell);

headerRow.Cells.Add(claimValueCell);

claimsTable.Rows.Add(headerRow);

TableRow newRow;
TableCell newClaimTypeCell, newClaimValueCell;

foreach (Claim claim in claimsIdentity.Claims)
{
    newRow = new TableRow();

    newClaimTypeCell = new TableCell();
    newClaimTypeCell.Text = claim.ClaimType;
    newClaimTypeCell.CssClass = "CellStyle";

    newClaimValueCell = new TableCell();
    newClaimValueCell.Text = claim.Value;
    newClaimTypeCell.CssClass = "CellStyle";

    newRow.Cells.Add(newClaimTypeCell);
    newRow.Cells.Add(newClaimValueCell);

    claimsTable.Rows.Add(newRow);
}
this.Controls.Add(claimsTable);
Step 7: Run the project. It will show the screen as below.

Please refer the next post for further steps.
Implementing Role Based Access Control on ACS - Part 2

0 Responses to “Implementing Role Based Access Control on ACS - Part 1”

Post a Comment