Post date: Dec 22, 2011 8:45:31 PM
Background
QBO 3's security configuration uses much of the same security configuration as QBO 2.0, including:
Person table defines valid users
SystemRole table defines roles
SystemFunction table defines modular functions (e.g. AttachmentInsert, ContactUpdate)
SystemMember: maps Persons to SystemRoles
SystemPermission: maps SystemFunction to SystemRole
Statement Permissions
Each DbStatement and class method can be tagged with required permissions, which correlate to a row in the SystemFunction table. If you do not explicitly set a Permission attribute on a Statement, by default, the Permission property will automatically assume {{Table}}{Name}. For example, a statement in Valuation.config called "VerifyComps" would automatically assume a Permission of "ValuationVerifyComps".
If you wish to control the Permission explicitly, you merely specify the Permission attribute in the statement. For example, the SmartWorklistMember.config file includes a Cancel statement that should be restricted to managers.
<Statement Name="Cancel" Permission="SmartWorklistMemberBulkComplete" Query=".../>
This implies:
A System Function row called 'SmartWorklistMemberBulkComplete' exists, and
One or more System Roles has permission to this function
The DbStatement.Permission property will cause AbstractObject to call a VerifyPermission method prior to executing the statement.
Note that in QBO 2.0, if a System Function is not defined, an error will be raised. In QBO 3, if a System Function is not defined, two things may happen in QboMembershipUser.HasPermission:
The SystemFunction will be automatically created (unless qbo.Security.Properties.Settings.Default.SystemFunctionAutoCreate is set to false)
The qbo.Security.Properties.Settings.Default.SystemFunctionMissing value will be returned, and it defaults to true. In other words, if your are lazy about security setup, users will get away with executing stuff they probably should not be. To prevent this, modify the SystemFunctionMissing value in web.config to false:
<applicationSettings>
<qbo.Security.Properties.Settings>
<setting name="SystemFunctionMissing" serializeAs="String">
<value>False</value>
</setting>
</qbo.Security.Properties.Settings>
</applicationSettings>
Public Permissions
In some cases, it is useful to enable permissions to all users, including anonymous (not logged in) users. In this case, you can tag a Statement with the 'Public' permissions. Examples include:
Person AccountLookup: this is used for password resets and such.
Granting access to property information for an REO Sales site
Granting access to property images for a listing site
Recording Permissions
In an ideal world, QBO clients would think through their security models prior to implementing projects. In an agile development world, they will often decide on their security requirements after they've configured the QBO components to fit their business model. The combination of auto-creating SystemFunctions with the ability to record permissions enables QBO client to achieve good security setup with a minimum of effort.
Under a standard install, a power user can configure the custom templates, statements, services, and listeners needed. During the course of unit testing, SystemFunctions matching custom components will be automatically created. Once unit testing is done, a power user or security administrator should:
Create one or more System Roles as dictated by their business organization,
For each role, navigate to the role's Summary page, and under the Permissions panel, choose Options > Record
This will launch a new window, where they can Start, Save and Stop recording permissions
Click on the 'Start' button
In their main window, conduct unit test(s) covering all the functionality the role should have
In their recording window, click on the 'Save' button
Note that if there are BDD specs covering the required functionality, one can merely:
Start recording
Run spec(s)
Save the recording
ASP.NET MembershipProviders
QBO 3 uses the standard ASP.NET MembershipProvider classes, including overrides:
QboMembershipProvider: authenticates credentials against the Person table
WindowsMembershipProvider: assumes Windows authentication, but the user must exist in the Person table
FacebookProvider: uses Facebook authentication, but the user must exist in the Person table
The membership providers works with the MembershipUser class (or derived classes). QBO3 includes a QboMembershipUser which combines both the MembershipUser class (via inheritance) and the qbo.Application.Interfaces.IUser.
IUser Interface
All QBO 3 classes handle security via classes that implement the IUser interface:
UserID: represents the PersonID in the Person table
HasUniversalAccess: if true, bypasses the extranet security model
HasPermission: checks to see if a user has permission to a System Function
IsInRole: checks to see if a user is a member of a System Role
Note that the HasPermission behaves a bit differently in QBO 3 than in QBO 2.0 if a System Function is not defined:
QBO 2.0: raises an error if the function is not found in the SystemFunction table
QBO 3: returns true if SystemFunctionMissing is true, otherwise returns false
The qbo.Secuirty application setting SystemFunctionMissing allows you to set the system up to be "permissive" during development, and then lock it down prior to rolling out to a production environment. The default value is true.
Configuration File Security
Custom configuration elements (such as IFileObject) can leverage a Permission configuration element to customize security settings. For example, the FileObject.ashx endpoint provides methods to download files (ReadFile) and list files in folders (ListFiles). By default, the System Function 'ListFiles' will be used to see if a user can execute the ListFiles method.
However, assume Power Users can list file from the Amazon S3 repository, but only Administrators should be able to list files from the Local File repository. In this case, the permissions for these methods may be overridden in the FileObject.config file as follows:
<FileObject>
<FileObjects>
<FileObject Name="LocalFile" Type="qbo.Attachment.FileObjects.LocalFile, qbo.Attachment" Uri="...">
<Permissions>
<Permission Method="ListFiles" Role="Administrators"/>
</Permissions>
</FileObject>
<FileObject Name="AmazonS3" Type="qbo.Attachment.Amazon.S3FileObject, qbo.Attachment.Amazon" Uri="...">
<Permissions>
<Permission Method="ListFiles" Role="Power Users"/>
</Permissions>
</FileObject>
</FileObjects>
</FileObject>
Such configuration does not come "for free"; the FileObject configuration classes are coded to check for such configuration file settings:
// From FileObject.ashx: this handles retrieval of a FileObject based on a query string.
qbo.Attachment.Configuration.FileObject config = GetFileObjectConfig(Parameters["FileObject"] as String);
// CheckPermission will raise an error if the user does not have permission
config.CheckPermission(User, "ListFiles");
// Create the IFileObject and continue on
IFileObject fileObject = Configuration.Create(config, User);
...