Authentication is the act of verifying a user's identity based on credentials they have presented. Authentication in the FileNet® P8 4.0 Content Engine functions differently, depending on how a request arrives at the server. The Content Engine server accepts incoming requests over two transport protocols: Enterprise Java™ Beans (EJB) and Content Engine Web Service (CEWS) transports.
The FileNet® P8 4.0 Content Engine resides within a Java 2 Enterprise Edition (J2EE) application server, and uses the Java Authentication and Authorization (JAAS) standard as the basis for authentication. The JAAS programming model is a standard Java framework that manages authentication and authorization. FileNet P8 Platform leverages JAAS to perform authentication, but not authorization. (Authorization is performed by FileNet P8 Platform code.) Authentication occurs between a J2EE client application, a J2EE application server, and one or more JAAS LoginModules.
Note: The FileNet P8 Process Engine does not run under a J2EE application server at this time, and is therefore unable to directly leverage the JAAS standard to support authentication and single sign-on (SSO) solutions. The Process Engine delegates its authentication operations to the Content Engine server.
Authentication over the EJB transport is handled through the use of the JAAS framework. FileNet code is not involved in this authentication process. Callers are authenticated by the J2EE application server before they can access the EJB layer. A JAAS Subject is created that contains the credentials of the authenticated user, and the Subject is returned to the client application.
Authentication over the web service transport is handled differently and FileNet code is involved in the authentication process of a web service based client. The WS-Security standard defines how security credentials are formatted and inserted in a web service request. When a web service request arrives in the FileNet P8 Content Engine server, the Content Engine web service listener extracts the WS-Security header and, based on its contents, performs a JAAS login. If this JAAS login is successful, the web service listener passes the request to the Content Engine EJB layer within the EJB container.
The Content Engine provides out-of-the-box support for the WS-Security Username/Password Token profile, as well as the Kerberos profile. However, to be able to use binary security tokens as defined in the WS-Security standard, FileNet P8 Platform provides a pluggable authentication mechanism—the Content Engine Web Service Extensible Authentication Framework (WS-EAF). WS-EAF consists of a set of conventions for writing a custom JAAS LoginModule that is able to interact with the FileNet P8 Content Engine web service listener to obtain the credentials that are present in a WS-Security header of an incoming request packet. For more information, see the WS-EAF Developer's Guide. This document contains details and code samples for extending the framework.
Authentication occurs in JAAS LoginModules which are specified in a JAAS configuration file. The use of JAAS configuration files allows authentication to be dynamically configured for both clients and servers in a J2EE environment.
Generally, a Java client program accessing the Content Engine should use the installed JAAS configuration file for the relevant application server (such as, jaas.conf.WebSphere, jaas.conf.WebLogic, or jaas.conf.JBoss). A client can also choose to use jaas.conf.WSI. In this case, the definition of the FileNetP8 stanza in the configuration file uses the Web Services transport, rather than the default EJB transport.
The configuration file contains one JAAS configuration (stanza), and within each JAAS configuration (stanza) is a list of LoginModules. Each entry in the list specifies the fully qualified name of a Java LoginModule class, a flag ("required", "optional", "sufficient", or "requisite"), and options for that LoginModule. The FileNet-supplied stanzas are the following:
This configuration should be used by all standalone (thick) Java clients. For compatibility, this stanza can also be used by servlet-based Java clients (such as, the FileNet Workplace application), although the FileNetP8Server stanza is now supplied for this purpose. When using the jaas.conf.WSI file, this stanza specifies the Web Services transport, rather than the EJB transport (specified in this stanza for the jaas.conf.
(Not for client use.) This configuration is used internally by the Content Engine server's Web Services transport handling processes, and should not be used by clients. You can modify this stanza, but only if you are using WS-EAF.
This configuration should be used by clients running within an application server container. An example would be servlets such as FileNet Workplace.
This configuration can be used by Java clients (standalone or within a servlet) that need to use the Web Services transport, rather than the default EJB transport. Another way to accomplish this is to use the jaas.conf.WSI sample configuration file with the FileNetP8 configuration.
(Not for client use.) This configuration is used internally by the Web Services transport handling processes, and should not be used by clients.
(Not for client use.) This configuration should be used only for JBoss installations, and is used, in this case, to define the LDAP and (possibly) Kerberos login modules. This should not be used by clients.
There are a number of other stanzas (such as, Credentials, ReceivedCredentials, HttpCredentials) that are required by the server while handling the Web Services transport or using the Systinet admin console. These stanzas can be removed safely from a JAAS configuration file used by a client.
When a client application attempts to authenticate, the JAAS framework dynamically determines the set of LoginModules to invoke based on the contents of the configuration file. Authentication succeeds only if all LoginModules marked either Required or Requisite succeed. If no Required or Requisite LoginModules succeed, then at least one Sufficient or Optional LoginModule must succeed.
FileNet supplies a set of sample JAAS configuration files. You can use them as samples when you set up your own configurations. The FileNet P8 installation program stores these sample files in the <installation_directory>\Programs\FileNet\CE_API\config\samples directory. Each application server has slightly different requirements, so the files are named for the supported application server environments: jaas.conf.WebLogic, jaas.conf.WebSphere, and jaas.conf.JBoss, and a special web service transport configuration file, jaas.conf.WSI.
Authorization to access objects within an object store is verified once authentication has occurred. Every object has its own security settings. Where multiple versions of a document exist, each version has its own security settings.
Assets managed in the Content Engine and Process Engine are protected and can be seen or modified only according to a user's access rights. Each object has its own security, which controls a user's (or group's) access to that object. An object can have several rules that govern access to it - for example, users in GroupA might have permission only to view the object, while UserB has permission to view and modify the object. Each rule (or "access control") is represented by a Permission
object, which establishes the access granted to a user or group (the "grantee"), and contains a reference to the user or group being assigned the permission. For more information about users and groups, refer to the Grantees topic, and to the reference help provided for the User
, Group
, SecurityPrincipal
, and Permission
interfaces.
The access level specifies the access rights (such as read and write permission) held by or denied to the referenced grantee, and determines the activities the grantee can perform on objects. A system administrator is typically responsible for establishing the type of access granted to users and groups. Note: In the security model, "deny" takes precedence over "allow", which can lead to counterintuitive expectations. For example, if you "deny" write access to a group and then "allow" write access to a specific member of that group, that member's write access is still denied.
A Permissions
collection represents the full set of access control entries (ACEs) associated with an object and forms the object's Access Control List (ACL). To grant rights, call methods on the AccessPermission
object to set the appropriate property, add the permission to the object's permissions list, and then save the modified AccessPermissionList
collection on the object. Removing access rights is a similar process. For a code sample that illustrates how to set access rights, see Working with Security.
Be aware that access to an object can also be affected by properties that are set at the Content Engine level. Notably, the settings of the ModificationAccessRequired and TargetAccessRequired properties can further restrict a user's access to, and ability to modify, an object's custom properties and its object-valued properties. You cannot set or retrieve the values of the ModificationAccessRequired and TargetAccessRequired properties via the Content Engine API. However, depending on the requirements of your application, you might need to understand the effect these properties can have on object access. For more information, refer to the Property modification access and Target access required topics in the Content Engine documentation.
A grantee is either an individual user or a group of users. A user can be a member of zero, one, or more directory service groups, and a group can contain zero, one, or more subgroups. (Note: Any user account that can successfully log on to a FileNet P8 domain is automatically added to the #AUTHENTICATED-USERS special account, which is an internally managed logical group, the members of which are authenticated user principals.) A FileNet P8 realm consists of a set of related groups and users. A realm is normally mapped to a directory partition in a directory server. The primary use of a Realm
object is to retrieve lists of the groups and users in the realm.
A user account is defined to the Content Engine server using tools provided by the directory service, for example, Microsoft® Active Directory®, Microsoft® Active Directory Application Mode (ADAM), Microsoft® Active Directory Lightweight Directory Services (AD LDS), Sun Java System Directory Server, or Novell eDirectory. A User
object exists in the Content Engine API as part of the security interface that allows a particular user to access a Content Engine resource. A Group
object represents a set of user accounts. Access rights (permissions) are assigned to individual user accounts and/or to the groups to which the individual user belongs.
Security on objects, such as folders and documents, can pertain to particular groups. These groups, and the users and subgroups that make up the group's membership, are typically defined and created by a system administrator using tools provided by the directory service. You cannot call a Content Engine API method to create a new group or user; however, you can instantiate a Group
or User
object that is defined to your directory service. You can retrieve a collection of groups and a collection of users then retrieve elements from the collections, or you can call methods on the Factory
classes for the type of object (group or user) you wish to instantiate. You can then call methods on the object to retrieve information about it, such as name and ID.
The way in which your application retrieves user and group information can affect system performance; refer to Role-Based Security for information on performance considerations.
Encryption/decryption logic of Content Engine credentials is centralized in a single shared module used by all Content Engine code that needs to store or retrieve credentials. The master key for encrypting and decrypting credentials is generated and stored during installation of the Content Engine software. (See Content Engine Encryption for more information.) Encryption information is also specified in the CEMPBoot.properties file. (See the descriptions of the CipherKeyLength, CipherAlgorithm, and EncryptedPassword properties in the CE Bootstrap Properties topic of the Security section of the Content Engine Administration documentation.
Clients can use the public Encryption
API to encrypt sensitive properties, such as passwords, that it sends to the Content Engine server. Use of these encryption methods in the API is only necessary if you are writing an administrative application that sets or resets the passwords on objects such as a Rendition Engine, or a fixed content provider. These password maintenance operations are typically performed through the Enterprise Manager tool, rather than through a custom application.
If you do need to write an application that resets system passwords, then you must include the JAR file for the Bouncy Castle 1.4.x provider in your CLASSPATH. The encryption is done using the public key retrieved from the Domain
object associated with the object containing the sensitive property. Once the property is received on the server, it is decrypted with the domain's private key, and then encrypted with the Content Engine master key prior to being persisted. Thus, this mechanism is intended to encrypt values only during transmission to the server, where they are immediately decrypted.
Static methods are available for encrypting bytes
, chars
, and strings
. (Chars
and strings
are UTF-8 encoded prior to being encrypted.) Note that the use of the method that encrypts strings is discouraged, as strings are immutable, so the sensitive data can remain in memory, posing a security risk, or it can be inadvertently written to disk as a result of exception handling or logging activity. Any char
or byte
array passed to an encrypt
method is overwritten once the encryption has been performed. If the application needs to use the sensitive data after encryption, which should be an unusual case, it must make a copy prior to encryption.
The IBM FileNet P8 Content Engine has numerous security-related caches, some associated with the object store and others associated with server security configuration. As with other Content Engine caches, most of these caches are based on a least-recently-used (LRU) algorithm and some also have an associated TTL (time-to-live). Caches have a configurable maximum entries attribute that defines the maximum number of cached entries allowed. When this value is exceeded, the least recently used element(s) are removed to make room for the new, more recently used element(s). The TTL (if applicable) associated with any given cache element defines the amount of time that the cached value should remain before being refreshed. TTL values are also configurable. Since characteristics of a cached element can change (for example, when the security permissions on an object get updated), cached values are refreshed periodically to provide a mechanism for those changes to take effect.
For performance reasons, the Content Engine keeps a cached copy of the users, groups, and realms returned from the database of your system's configured authentication provider. Cache refresh rates are controlled by cache configuration settings that specify a "time-to-live" (TTL) value for cached information. The default values are the following:
Realms
returned by a call to EntireNetwork.get_AllRealms()
- 12 hoursUser
or Group
associated with a realm - 1 hourUsers
or Groups
collection associated with a user or group - 1 hourThe consequences of caching user, group, and realm information can include the following unexpected behaviors:
AccessPermissionList
collection.Security of objects in the Content Engine is not compromised by the above consequences.
Since adding and removing groups tends to happen much less frequently than adding and removing users, sites and applications that use mostly groups and not users as security grantees will be less affected by the above consequences.
Integrated logon (also called "single sign-on" or SSO) is the feature whereby a user can access multiple systems after being authenticated just one time. The Content Engine server takes advantage of an earlier Windows® logon to authenticate a user (that is, establish the user's identity) without requiring the user to provide credentials (such as username and password) again for each subsequent logon.
Using the SSO support provided in FileNet P8 Platform, your custom applications can integrate with any SSO vendor (such as CA/Netegrity or IBM® Tivoli®) that provides JAAS-based authentication on the platforms supported by FileNet P8. If an SSO vendor has provided JAAS LoginModules that work with a given application server, FileNet P8 can support that single sign-on solution for Java-based applications. Note that there are limitations to this ability to integrate with SSO providers. For a complete list of limitations, see the "Single Sign-on Integrations via JAAS" topic in the Enterprise-wise Administration Security Guide. A few of the important limitations for developers of custom applications are the following:
For clients that use Kerberos as the SSO provider, see the Implementing Kerberos topic in Working with Security for the requirements and configuration steps necessary.
Security for an object is specified in terms of access rights (permissions). Access rights specify whether a user or group can view the object and what the user or group can do with the object.
A class has a default set of access rights. When a new object is created based on the class, these default permissions are assigned to the object and are referred to as an object's basic permissions. The object's Permissions property is populated when basic object permissions have been set for an object. As an example, if the minimum level of access rights (AccessLevel.READ
or AccessLevel.VIEW_PROPERTIES
) is defined for a Document
class, a user who is allowed that level on a new Document
object would only be able to view the object's properties. Basic permissions can be overridden by setting explicit permissions or by inheriting permissions from a security template. For example, you could set additional permissions on the
Document
object to allow a user to not only view document properties but also to view and modify document content.
To retrieve the basic permissions on an object, call get_Permissions()
. This method returns the value of the object's Permissions property. You can call get_Permissions
on the following objects:
Action | IndexJob |
ActionConsumer | Link |
Annotation | Marking |
ChoiceList | ObjectStore |
ClassDefinition | PropertyTemplate and its subinterfaces |
Containable and its subinterfaces | SecurityPolicy |
Domain | Storage Area |
Event | StoragePolicy |
IndexArea | TableDefinition |
Note that the Marking
interface is the only one with a Permissions property that is not used to calculate effective access of the primary object. See Marking Object Permissions for more information.
To set basic permissions on an object, call set_Permissions
, passing in a collection of AccessPermission
objects. See Setting Permissions in Working with Security for a code snippet.
To retrieve basic access rights for a user, you can call getAccessAllowed
on an IndependentlyPersistableObject
.
This method returns a bit mask representing the current caller's effective access to the object.
Role-based security means that permissions are based on group membership. Using role-based security provides performance benefits and is recommended over assigning permissions to individual users.
Calling methods that return collections of User
and Group
objects (such as get_Users
on the Group interface and findUsers
and findGroups
on the Realm
interface) involves a lookup operation on the directory server. Response times for the lookup operations associated with these calls increase with the number of entries to return, and are further degraded when the lookup is performed on a directory server with limited system resources. Because the number of groups in a realm is typically much smaller than the number of users in the realm, group lookups will yield better response times than user lookups. For example, when constructing your application, call Realm.findGroups
first and make calls to Group.get_Users()
only as necessary. When returning collections from a very large directory of groups and users, use the filtering capability provided by parameters to the findGroups
and findUsers
methods to limit the number of items returned.
When calling get_MemberOfGroups()
on a User
or Group
object that belongs to a nested set of groups, all groups to which the user or group belongs are returned.
You can restrict a group membership search to search within the realms configured in FileNet Enterprise Manager by setting the RestrictMembershipToConfiguredRealms property on the DirectoryConfiguration
class. When the value of this property is false
(the default), the Content Engine server searches the following types of group memberships:
If the value of this property is true
, the Content Engine server searches the first two types above, but ignores the third type. More specifically, it does not generate an error when the group membership search encounters a realm that is not configured in FileNet Enterprise Manager. Instead, it writes an INFO-level message to the Content Engine server error log, skips this specific group membership, and moves forward. In other words, if this Boolean
property is enabled, the Content Engine server ignores any cross-realm group memberships involving realms that are not configured in FileNet Enterprise Manager.
With the exception of Windows Active Directory Application Mode (ADAM), the RestrictMembershipToConfiguredRealms property is supported in every type of directory service provider supported in IBM FileNet P8 Content Engine 4.5. In the case of ADAM, which does not support cross-realm group memberships, the property is retained on the DirectoryConfiguration
class for consistency across all supported directory servers, but the setting of the property on a DirectoryConfigurationADAM
object has no meaning and is ignored. (Note that RestrictMembershipToConfiguredRealms is specified in the DirectoryConfiguration
class, which is inherited by its child classes, such as DirectoryConfigurationADAM
.)
There can be security implications if you choose to restrict membership searches to only the realms configured in FileNet Enterprise Manager. The following scenario is one example:
The security administrator configures two Active Directory domains, X and Y. The administrator then configures Group A in Domain X and configures Group A to belong to Group B in Domain Y. Group B is then denied access to Content Engine. As a result, at this point, Group A in Domain X is also denied access to Content Engine. The administrator then removes Domain Y from the configuration and sets the DirectoryConfigurationAD.RestrictMembershipToConfiguredRealms
to true
(that is, use only local group memberships) in Domain X. Now the pre-configured Deny action for Group A is no longer in effect and security might be compromised.
Carefully examine security implications before you choose to ignore cross-realm group memberships on lookup operations.
A security marking is an additional level of security that can be assigned to an object, and is represented by a Marking
object. A Marking
object combines metadata behavior with access control behavior in a way that allows an object's access control to change by changing a property value. Each marking has a string metadata value that is assigned to a property value when the marking is applied to an object.
A Marking
object represents a single item in a marking set, which is also called a security category. The markings in the marking set define the list of possible values for a single or multi-valued property of an object. A marking set is associated with a property on an object class. As an example, in a marking set called "Security Codes", the individual markings might have string values such as "Top Secret", "Secret", "Confidential", and so on. After you assign the "Security Codes" category to a Document
object, you can assign one or more of its markings to the document by setting the value of one of its properties. (Note that an object can be assigned only one security category, but multiple markings.) For example, you might assign a value of "Top Secret" to a custom property called Clearance on a document. After the authorization service evaluates the permissions on a particular object, it also evaluates the markings on the object. A security principal who wishes to access that document must have sufficient access from all assigned markings.
You can set multiple values for the Marking property on a new object. If you attempt to create an object, passing in a Marking property value for which the user has been granted Add rights but not Use rights, the method throws an "access denied" exception.
Creating marking sets and markings requires FileNet P8 domain administrator access rights. Marking sets and markings are stored in the Content Engine GCD. A marking set is associated with a property on an object class. You cannot create a Marking
object via the Content Engine APIs. However, you can create an instance of a persisted Content Engine marking. For a list of ways to instantiate a Marking
object and for a list of objects to which you can assign one or more markings, refer to the reference help for the Marking
interface. (For information about creating the Content Engine Marking
and MarkingSet
objects, see the Markings topic in the Content Engine Security documentation.)
From an instance of a Marking
object, you can obtain its ID, the ID of its class description, and its display name. In addition, you can call methods that return the marking's value and the set of access rights that are associated with the marking value when the marking is applied. You can also retrieve the marking's constraint mask. The constraint mask is a bit mask that represents the set of access rights affected by the Marking when it is applied to an object. For information on each of these methods, refer to the online help for the Marking
interface. For code examples, refer to Working with Marking Objects.
Any object that can have a marking can be assigned one or more markings. A marking that is assigned to an object is called an active marking. The list of all markings assigned to a single object is represented by an ActiveMarkings
collection. You cannot create an ActiveMarking
object or an ActiveMarkings
collection with the Content Java API. However, through an object's ActiveMarkings property you can instantiate an ActiveMarking
object from which you can then retrieve the Marking
object assigned to the object.
Marking set information is cached, in much the same manner user and group information is cached. A registry setting called MarkingSetTTL sets the refresh time for the cache, like the similar settings for user and group caches. The default setting is 3600 seconds (1 hour). The cache is also refreshed when a marking set is modified (for example, a new marking is added to the marking set), and the cache is expired when a marking set is deleted.
A user's access to an object to which markings have been applied or modified might be affected due to time lags in updating the cache. For more information, refer to Security cache in the Content Engine Security documentation.
When retrieving the permissions on a Marking
object, note that the permissions returned by the Marking.get_Permissions
method do not represent access rights to the Marking
object of which they are a part. Rather, they are a collection of access rights that are associated with the marking value and are applied when the marking is assigned to an object. This method also returns special permissions that determine who can apply the marking to and remove the marking from an object. The next few paragraphs describe these special "add", "remove", and "use" permissions.
A user or group must be granted specific permissions to perform operations relevant to a marking that are performed by the authorization service: add, delete, and use a marking. You must have Add permission (AccessRight.ADD_MARKING
) to be able to assign (add) a marking to an object, or Remove permission (AccessRight.REMOVE_MARKING
) to delete a marking from an object.
The "use" permission (AccessRight.USE_MARKING
) determines whether a constraint mask will be applied when a marking is assigned to an object. If a user has been denied the "use" access right, then the value of the ConstraintMask property is applied to, and overrides, the object's preliminary Effective Access Mask as computed by the authorization service.
To obtain the access mask for a Marking
object based on the current user and the Marking
object's permissions, call get_MarkingUseGranted()
. From the returned value, you can determine if a given user has the appropriate rights to perform marking-related operations on an object.
In order to apply a Marking
to an object, the MarkingSet
that contains the Marking
must first be associated with a PropertyDescription
from the object’s ClassDescription
. This association has the effect of constraining the possible values that can be assigned to the property defined by the PropertyDescription
to values associated with the Markings
in the Marking Set
.
The following topics provide information about specific marking-related properties: MarkingSets, MarkingSet, IsHierarchical, ActiveMarkings, and ConstraintMask.
The Domain
object's MarkingSets property specifies a collection containing the MarkingSet
objects associated with a given domain.
Any object to which a marking can be assigned has a MarkingSet property in its PropertyDescription
object. The value of this property defines the possible marking values that can be assigned to the property described by the PropertyDescription
.
You can use this property to retrieve a list of Marking
objects that can be assigned to an object by a particular security principal. You can display the returned markings in a user interface from which a particular user can make selections. As an example, the MarkingSet property on a security category called "Security Codes" might contain the markings "Top Secret", "Secret", and "Confidential".
A MarkingSet
object can be defined as hierarchical or non-hierarchical, and is reflected in the value of its IsHierarchical property. A non-hierarchical marking set contains one or more markings, each independent of all others. A hierarchical marking set arranges markings in a simple, single branch hierarchy. Each marking has a superior marking (which must be in the same set), except for the top marking (its superior is null).
The purpose of hierarchical marking sets is to support an order of precedence when evaluating access rights. A marking in a hierarchical marking set explicitly grants access rights to a set of security principals. In addition, it also implicitly grants the same rights for all markings that are inferior to it in the hierarchy.
All objects that can have markings will have an ActiveMarkings property, which is a list-valued property that returns all ActiveMarking
objects that are assigned to the object in question. The list is a Values
collection whose elements are the ActiveMarking
objects that have been assigned to the object. Through an object's ActiveMarkings property you can get an ActiveMarking
object. From that object instance, you can then call getMarking()
to retrieve the actual Marking
object that has been assigned to the object in question. For a code sample, refer to Working with Marking Objects.
An object's ConstraintMask property represents the access rights that are affected when a marking is applied to the object. The constraint mask is specified when the Marking object is created. When the marking is applied to an object, the constraint mask serves to subtract from the object's preliminary Effective Access Mask those access rights that correspond to the bit settings in the mask.
Whether or not the constraint mask will be applied to an object's preliminary Effective Access Mask is determined by whether or not a security principal is granted or denied the "use" access right for a marking. If the security principal is granted "use" permission, the constraint mask is not applied. If the security principal is denied "use" permission, the object's access control is modified based on the constraint mask. For example, if all bits of the constraint mask are 'on' and a user has been denied the AccessRight.USE_MARKING
permission, when the marking is applied to a Document
object, the bits in the constraint mask are subtracted from the Document
object's preliminary Effective Access Mask. The computed result (the Effective Access Mask) prevents the user from accessing that document.
If you assign a marking to an object, and the marking's permissions have not granted the user or group the "Use" access right (AccessRight.USE_MARKING
), then the rights represented by bits in the constraint mask are subtracted (removed) from the preliminary Effective Access Mask that was computed by the authorization service. The computed result of this subtraction is the Effective Access Mask for the object.
You can retrieve the value of the constraint mask by calling get_ConstraintMask()
on the Marking
interface.
A newly-created object acquires its default permissions directly from its class. The ClassDescription
interface's get_DefaultInstancePermissions
method returns the default permissions for an object belonging to the class. You can use this method to determine if the class's permissions are appropriate for your application or to display the default permissions in a user interface and allow the user to modify the permissions when you are creating a new object of this class.
An object can also acquire permissions through inheritance and from a security policy.
Security inheritance is a customizable mechanism for managing access control based on inherited security relationships. The security relationships can be assigned to reflect the relationships inherent in your application object model.
A Document
or CustomObject
object (any class implementing the Versionable interface) can inherit security based on the following sources:
Folder
object identified as a security parent in the SecurityFolder property for the child object. Multiple, different security parents (Folders) can be specified using object-valued properties on the child object.A Folder
object always inherits its permissions from its parent folder. A Document
or CustomObject
object's security parent is reflected in the value of its SecurityFolder
property. You can indirectly set the SecurityFolder
value for an object at the time it is filed into a folder by calling the Folder.file
method and specifying DefineSecurityParentage
as the value for the defineSecurityParentage
parameter. The folder into which the object is filed is then set as the SecurityFolder
value.
Note: Although it is generally assumed that an object's SecurityFolder
value will identify the folder in which the object is filed, this is not a constraint. The SecurityFolder
value can be any Folder
object.
However, setting a child object's SecurityFolder
property alone does not guarantee that the child object will inherit a specified parent's permissions: only those permissions that are inheritable to the depth (level) of the child object (in an abstract inheritance tree) will be inherited. Use the set_InheritableDepth
method on the Permission interface to specify the depth to which a parent object's security can be inherited by setting the method's parameter to a value corresponding to a level in the inheritance tree (where 0 is no inheritance, 1 is for immediate child objects only, and -1 is for all child objects).
You can determine the source of an inherited permission by retrieving the value of the Permission
object's PermissionSource property, for example, by calling Permission.get_PermissionSource()
. Permission entries with a source of PARENT have been inherited.
Inheritance of security for any given child object is calculated dynamically: whenever an access check is performed on the child object, or the Permissions
collection associated with the child object is retrieved. The inherited access control entries (ACEs) are not persisted in the child object's access control list, but are calculated from the inheritable ACEs for the security parent specified in the child object's SecurityFolder property
.
A security parent or parents also can be designated using object-valued properties. Use the INHERITANCE setting for the SecurityProxyType constant. You can set SecurityProxyType
using PropertyTemplateObject.set_SecurityProxyType.
When using the INHERITANCE type of security proxy, it is possible to specify multiple security parents for an object. You can do this by assigning SecurityProxyType.INHERITANCE
values to more than one object-valued property on the object. The resulting security descriptor for the object is calculated by merging the inheritable ACEs of the different security parents with the child object's persisted ACEs.
For information about security inheritance rules, refer to Understanding security inheritance topic in the Content Engine Security documentation.
Security policies allow greater administrative control over object security than that provided by standard security. For example, instead of an object inheriting its security through a security parent, you can elect to use the security policy feature to assign access rights based on an object's state changes.
Security policies support the following two security management mechanisms:
Enabling version state security automatically applies access rights to versionable objects (Document
and its subclasses) as the object moves from one state to another. This behavior is seen with two-level versioning, in which the expectation is that as a document moves through four pre-defined states, access to that document will differ for each state. The four pre-defined document states are: InProcess, Released, Reservation, and Superseded. For example, when a document enters the released state (becomes the current major version), you might want all users to be able to view it, but if the document is superseded by a newer version, you might want only the document owner to be able to view it.
You can also choose application-managed security, in which state-based changes to both versionable and non-versionable objects (for example, CustomObject
or Folder
objects) are applied as the object transitions from one state to another. The definition of a state change in this case is entirely application-defined. For example, the application can define a state change as occurring when some specific period of time has gone by since the last modification to the object. As the object undergoes state changes, your application controls access to it by identifying points at which security should be changed and then explicitly applying access rights specified by a selected security template. This differs from an application directly modifying access rights at various times in that it provides a level of indirection and abstraction. The application still controls the nature and timing of access right changes, but the specific details of the changes are isolated to security policies.
The security policy is the mechanism for controlling access to an object as its state changes. The security policy is a container that holds a set of security templates. Templates hold a collection of predefined permissions that can be applied to a Document
, CustomObject
, or Folder
object. The template defines the exact security change that will occur when the template is applied to an object.
Security policies are created and a default security policy can be assigned to Document
, CustomObject
, and Folder
classes. (Typically, these tasks are performed by a Content Engine administrator.) An object's security policy is reflected in the value of its SecurityPolicy property. Users with appropriate permissions can remove the security policy from the class, or change the security policy on the class. When a new subclass of one of these classes is created, the subclass inherits the security policy of its parent class. However, after the subclass is successfully created, that security policy can be removed or changed by setting the object's SecurityPolicy property in the same manner as you set any other object-valued property.
Security policies offer flexible control over object security.
Document
, Folder
, and CustomObject
classes, or their subclasses. Document
objects and assign each a different security policy.Document
, Folder
, or CustomObject
objects, or any combination of the three object types. A security policy is made up of a set of security templates, each of which corresponds to an object's state. Each template contains the access rights that will be assigned to an object as a result of applying the template. When versionable objects (such as Document
) move from one versioning state to another, for example, from InProcess to Released, the appropriate security template is retrieved from the security policy and automatically applied to the object. "Applied" in this context means that the permissions defined in the security template are assigned to the object, replacing any permissions previously inherited from a security template. Your application can also explicitly apply a template to a versionable or non-versionable object. For more information, refer to Applying a Security Template.
From the Content Engine APIs, you manage and manipulate the security policy via the SecurityPolicy
object and SecurityTemplate
objects. For more information about these objects, refer to SecurityPolicy Object and SecurityTemplate Object topics.
A SecurityPolicy
object is an independently persistable, subclassable container object for a set of SecurityTemplate
objects. Each SecurityPolicy
object can contain zero or more application security templates and from zero to four versioning security templates. The SecurityPolicy
object's multi-valued, object-valued SecurityTemplates property contains the security templates contained in the policy. A SecurityPolicy
object can be associated with one or more Document
, CustomObject
, or Folder
objects, or any combination thereof that shares a common access control scheme. Associating a SecurityPolicy
object with an object allows the templates contained in the policy to be applied to the object. A single SecurityPolicy
object can contain versioning security templates, application security templates, or both.
Given the appropriate permissions, you can create a new SecurityPolicy
object, or retrieve, change, and save an existing one. You can also:
SecurityTemplate
objects to the SecurityPolicy
object.SecurityTemplate
objects from the SecurityPolicy
object. SecurityTemplate
objects contained in the SecurityPolicy
object.Modifications to an existing SecurityPolicy
object are not propagated to objects that refer to that policy.
For ways to instantiate a SecurityPolicy
object, refer to the SecurityPolicy
interface description in the reference help.
A SecurityPolicy
object can be associated with a Document
, CustomObject
, or Folder
object by setting the object's SecurityPolicy property. When you create the object, you can assign to it a maximum of one security policy. Multiple security policies are not allowed on a class definition or a single object instance. If you do not assign a security policy to the new object at creation time, the value, if any, specified as the default (in the SecurityPolicy property description of the class) is copied to the object instance. When creating subclasses of a class that has an associated security policy, the new subclass shares the security policy with its parent class.
As a versionable object undergoes versioning state changes, its permissions, based on its security policy, are modified. If the versionable object has no associated security policy, its permissions remain unchanged when its versioning state changes. When you set the SecurityPolicy property of a Document
object for the first time, or you change it to refer to a different security policy, the new policy is applied to the current (latest) version of the document in the version series.
An object's security policy can also change when you change the class of a Document
, CustomObject
, or Folder
object. The value for the object's SecurityPolicy property is changed according to the same rules as for other properties. For more information, refer to the reference help for the changeClass
method.
You can remove a security policy from an object, or remove security policy objects from the object store.
To remove a security policy from an object, set the object's SecurityPolicy property to null
. This removes from the object all permissions that were inherited from the security policy's templates.
Given the appropriate permissions, you can delete a security policy from the object store. Doing so removes the SecurityPolicy
object and all its contained SecurityTemplate
objects. You cannot delete an in-use SecurityPolicy
object. A SecurityPolicy
object is considered in use if there are any outstanding references to it. Outstanding references include when it is identified as a class default value or when the SecurityPolicy property of at least one Document
, CustomObject
, or Folder
object is set to the SecurityPolicy
object you want to delete. When any of the following occurs on a Document
, CustomObject
, or Folder
object, the associated SecurityPolicy
object will no longer be considered in use and you can delete it:
SecurityPolicy
object.null
.The SecurityTemplate
object is a dependently persistable object that contains the permissions that will be applied to an object. An instance of this object cannot be created or persisted independently of a parent SecurityPolicy
object. (For ways to create a new SecurityTemplate
object or retrieve an existing one, refer to the VersioningSecurityTemplate
or ApplicationSecurityTemplate
interface description in the reference help.) Using the SecurityTemplate
object's methods, you set its properties and permissions before adding it to a SecurityPolicy
object. The SecurityTemplates property of the SecurityPolicy
object reflects the templates contained within the policy.
A description of the permissions that the SecurityTemplate object represents can be obtained by getting the value of the object's TemplatePermissionDescriptions property. From this property, you can determine the template's AccessPermissionDescription objects, each of which provides descriptive information for an access right or level. The information, which you can use to populate security editing dialogs in a user interface, consists of the permission's access mask, permission type, and display name.
A SecurityTemplate
object can represent either an application security template or a versioning security template. The two types have the same object type, but are differentiated by their class IDs (GUIDs) and by their uses. Class IDs for the security template types are defined by the following constants: APPLICATION_SECURITY_TEMPLATE
and VERSIONING_SECURITY_TEMPLATE
. (Refer to the FileNet.Api.Constants namespace or filenet.com.api.constants package in the reference help.)
Use application security templates when you want your application to manage object security as an object's state changes. An application security template is a predefined collection of permissions that can be applied to a Document
, CustomObject
, or Folder
object. An application security template is never automatically applied; it must be explicitly applied to the object.
An application security template's ApplyStateId property associates the template with a particular state that is defined by your application. When the application determines that an object has transitioned to that state, the application can call the applySecurityTemplate
method on the object, specifying the value for the applyStateId
parameter as either a user-defined GUID or one of the pre-defined versioning state GUIDs. The method uses the GUID to locate and select the appropriate template to apply from those available in the SecurityPolicy
object associated with the object.
A user or group with permission to modify an object's security (AccessRight.WRITE_ACL
) can change an object's security by explicitly applying any of the enabled SecurityTemplate
objects contained in the SecurityPolicy
object.
A versioning security template is used exclusively to support the automatic update of a Document
object's permissions as its versioning state changes. A default versioning security template is available for each state through which a document version can transition: InProcess, Released, Reservation, and Superseded. The template's ApplyStateId property contains a value that corresponds to one of the four statically-defined GUIDs for each state. The GUIDs are defined as constants in the VersionStatusId
class as follows:
IN_PROCESS
RELEASED
RESERVATION
SUPERSEDED
When a versionable object's state changes, the template corresponding to the changed state is located from those available in the SecurityPolicy
object and is automatically applied to the object.
As an example, when a Document
object's version state changes from InProcess to Released, the associated SecurityPolicy
object is searched for a versioning security template whose ApplyStateId property is set to VersionStatusId.RELEASED
, and the permissions defined by that template are automatically applied to the object. If a security template has been previously applied to a versionable object, the permissions in the automatically-applied versioning template replace the previously-applied permissions.
A user or group with permission to modify an object's security (AccessRight.WRITE_ACL
) can change an object's security by explicitly applying any of the enabled SecurityTemplate
objects contained in the SecurityPolicy
object.
You can optionally disable an individual template in the SecurityPolicy
object. Disabling a template sets its IsEnabled property to false
. A disabled template remains a part of its SecurityPolicy
object container, but cannot be applied to an object. Disabling a template is useful when you are testing or developing security templates that make up a security policy.
Enabled templates of the appropriate type are applied to an object in the following circumstances:
applySecurityTemplate
method.changeClass
method.When the SecurityPolicy property of a versionable object is set for the first time or changed to refer to a different SecurityPolicy
object, the SecurityPolicy
object is searched for a template that corresponds to the current version status of the document, and the template is applied (that is, the permissions defined in the template are assigned to the object).
An application can modify the existing security on an object by calling the applySecurityTemplate
method on the Document
, CustomObject
, or Folder
interfaces. This method applies an individual security template, specified by the applyStateId
parameter, to the object. Using the parameter value, the method locates the SecurityTemplate
object whose ApplyStateId property corresponds to the value contained in the parameter.
When the method locates the template, it applies it to the object (that is, the permissions defined in the template are assigned to the object). Permissions from the template are applied to the object in the following order:
SecurityPolicy
object's PreserveDirectPermissions property is set to false
, the method deletes non-inherited permissions (that is, those that have been directly set on the object) and retains only inherited permissions; if set to true
, the method retains the non-inherited (directly set) permissions.SecurityTemplate
are added to existing permissions that were inherited from the object's security parent and to any existing non-inherited permissions.