Constable Authorization Engine Tutorial - Using the authorization policy
In the previous step, we've populated
an instance of the
AuthorizationPolicy
class with data representing
our document approval authorization policy. We're now almost ready to use
the CAZE's authorization policy services within the application. But before doing that,
we have to make sure to set up a feasible authorization context.
Authorization context
Simply put, an authorization context defines the principal used to resolve
role membership and the current state of the business object represented
by the authorization policy.
By default, the CAZE policy will use the
System.Threading.Thread.CurrentPrincipal
principal as the current principal. If this is not feasible, you can set the
AuthorizationPolicy.CurrentPrincipal
property to any System.Security.Principal.IPrincipal implementation that
suits your needs.
Let's assume that our document approval application will be used on a company's
Intranet, so we can use the integrated Windows authentication. The appropriate settings
in the application's web.config file would be as follows:
<authentication mode="windows">
The above configuration ensures that the ASP.NET environment will
set the System.Web.HttpContext.Current.User principal to the Windows
identity of the user accessing our application and the Windows identity will be used
to resolve role membership. (ASP.NET will set the
System.Threading.Thread.CurrentPrincipal property to the
System.Web.HttpContext.Current.User reference as part of the
AuthenticateRequest event processing.)
You might recall that in the previous step, we've added
the roles this way:
[Visual Basic]
docPolicy.Roles.Add(new WindowsRole("Author", "{DOMAIN}\Domain Users"))
docPolicy.Roles.Add(new WindowsRole("Reviewer", "BUILTIN\Administrators"))
[C#]
docPolicy.Roles.Add(new WindowsRole("Author", @"{DOMAIN}\Domain Users"));
docPolicy.Roles.Add(new WindowsRole("Reviewer", @"BUILTIN\Administrators"));
The above code maps users that are members of the "{DOMAIN}\Domain Users"
windows group to the Author role (the "{DOMAIN}" string gets replaced by the
System.Environment.UserDomainName value at runtime). Users that
are local administrators are mapped to the Reviewer role.
This way, we've ensured that CAZE will use Windows group membership
when executing the authorization checks.
Current state
The current state of the authorization policy is another important aspect of the
authorization context, because it also directly impacts the outcome of authorization
queries and checks. The current state is represented by the
AuthorizationPolicy.CurrentState
property and it defaults to the first state added to the
policy's
AuthorizationPolicy.States
collection. Most of the time, you'll want to set the CurrentState property to the state
of the business object for which you want to perform authorization, for example:
[Visual Basic]
Dim doc As DataRow = <load the document row from database>
Dim currentStateId As String = doc("state_id").ToString()
docPolicy.CurrentState = docPolicy.States(currentStateId)
[C#]
DataRow doc = <load the document row from database>
string currentStateId = doc["state_id"].ToString();
docPolicy.CurrentState = docPolicy.States[currentStateId];
We've loaded the document object from database and we've set
the
AuthorizationPolicy.CurrentState
property to the document's state. We're now ready to use the policy to actually perform authorization.
To sum it up, here are the steps your application will use to prepare the
CAZE policy for authorization:
-
Create and populate an instance of the
AuthorizationPolicy
class.
-
Set the
AuthorizationPolicy.CurrentPrincipal
to a
System.Security.Principal.IPrincipal implementation that will be used
by the policy to query the principal's role membership (or let the policy use the
System.Threading.Thread.CurrentPrincipal principal).
-
Set the
Policy.CurrentState
property
to the current state of the business object for which you want to perform authorization.
Authorization checks
After performing the above steps, we're ready to use the authorization policy's
authorization services. The services take into account the current authorization context and they're
represented by the following methods:
For example:
[Visual Basic]
Public Sub UpdateDocument(ByVal doc As DataRow)
' Load the authorization policy.
Dim docPolicy As AuthorizationPolicy = Me.LoadDocPolicy()
' Initialize the authorization context.
docPolicy.CurrentPrincipal = principal
docPolicy.CurrentState = docPolicy.States(doc("state_id").ToString())
' Perform the access check. The following call
' will throw an exception if the action isn't allowed.
docPolicy.ExecuteAction("Update")
' If we've got here, the Update action was executed.
' Remember the new document state and save it to DB.
doc("state_id") = docPolicy.CurrentState.Id
Me.UpdateDocumentInDatabase(doc)
End Sub
[C#]
public void UpdateDocument(DataRow doc)
{
// Load the authorization policy.
AuthorizationPolicy docPolicy = this.LoadDocPolicy();
// Initialize the authorization context.
docPolicy.CurrentPrincipal = principal;
docPolicy.CurrentState = docPolicy.States[doc["state_id"].ToString()];
// Perform the access check. The following call
// will throw an exception if the action isn't allowed.
docPolicy.ExecuteAction("Update");
// If we've got here, the Update action was executed.
// Remember the new document state and save it to DB.
doc["state_id"] = docPolicy.CurrentState.Id;
this.UpdateDocumentInDatabase(doc);
}
We've loaded the document approval authorization policy, initialized the
authorization context and executed the action representing the
UpdateDocument business object's method. After that, the new document's
state (and perhaps the modified document properties) were saved to the database.
Note: The AuthorizationPolicy can refuse to execute an action
even if the action is enabled. For more information, please see the
authorization policy determinism page.
|