The information in this section describes some of the tasks related to client-side security as you develop your applications.
Performing and using a Java™ Authentication and Authorization (JAAS) login consists of three steps: obtaining a LoginContext
object, calling the LoginContext.login
method, and impersonating the logged-in user to perform the actual work. This section provides some information and a code sample that illustrate how to perform these steps.
Obtaining a LoginContext
object requires a tag to indicate some particular configuration in the JAAS login configuration file. If your login configuration file has an entry for "other", then it doesn't matter what tag you use in the call to the constructor of LoginContext
, since the call will fall back to the "other" entry in the configuration file. You also need to supply a CallbackHandler
to provide the credentials (username and password). If you would like to be prompted for that information, you could just provide a new instance of one of Sun's sample callback handlers, such as com.sun.security.auth.callback.DialogCallbackHandler
(as shown in the example below) or TextCallbackHandler
.
The login
method calls the callback handler and if this is a BEA WebLogic® or IBM® WebSphere® application server the credentials are authenticated. For JBoss, credentials are not authenticated until they are used in an interaction with the server to fetch, save, or search for objects. Problems with credential authentication, such as an invalid password, can occur in different places depending on the application server you use to perform authentication. A successful call to the login
method for JBoss does not mean that the credentials have been authenticated.
A UserContext
object is associated with each thread that accesses the Content Engine Java API. A JAAS Subject
should be associated with the thread, by calling UserContext.pushSubject
, prior to making any calls that will cause the API to access the Content Engine server. Note that the UserContext
class provides a helper method that can perform the JAAS login for you in the common username/password case. This approach would typically be taken when using the Content Engine Java API over the web service transport. The example in this section uses the EJB transport for all subsequent Content Engine Java API calls. To instead use the web service transport, change the JAAS configuration stanza name in the UserContext.createSubject
call from "FileNetP8" to "FileNetP8WSI".
Java Example
// Perform login static void performLogin( Connection con, String userName, // Example: "username@testdom.local" String passWord) throws Exception { // *** Step 1: Obtain login context *** // Determine call back handler CallbackHandler handler = null; if (userName != null) { // Call user-created class that implements CallbackHandler handler = new UserPasswordHandler(userName, passWord); } else { handler = new DialogCallbackHandler(); } // Get login context LoginContext lc = new LoginContext("mysystem", handler); // *** Step 2: Call login method *** // Attempt login try { lc.login(); System.out.println("Login succeeded"); } catch (Exception exc) { System.out.println("Login failed"); throw exc; } // *** Step 3: Impersonate logged-in user *** // Get user context UserContext uc = UserContext.get(); // Determine subject Subject sub = null; if (userName != null) { // Example for EJB transport. Stanza name is FileNetP8 for EJB, FileNetP8WSI for WSI. sub = UserContext.createSubject(con, userName, passWord, "FileNetP8"); } else { sub = lc.getSubject(); } // Associate the JAAS Subject with the UserContext try { uc.pushSubject(sub); // do work } finally { uc.popSubject(); } }
The annotated sample code below illustrates how to set access permissions on a new object. The access mask defines operations that the grantee (user or group) is allowed to perform. Each bit in the mask represents an operation. If the bit is set, the grantee is allowed to perform the specified operation; if the bit is not set, the operation is disallowed for that grantee. In this case, the user named "test1" is being granted full control access to a document using the group of access rights represented by the AccessLevel
constant.
Java Example
{ //create a new permissions list AccessPermissionList apl = Factory.AccessPermission.createList(); //create a new access permission object AccessPermission ap = Factory.AccessPermission.createInstance(); // set access permissions ap.set_GranteeName("test1"); ap.set_AccessType(AccessType.ALLOW); ap.set_AccessMask(new Integer(AccessLevel.FULL_CONTROL_DOCUMENT_AS_INT)); // add the permissions to the list apl.add(ap); // create a document and add the permissions Document doc = Factory.Document.createInstance(os, ClassNames.DOCUMENT); doc.set_Permissions(apl); // save the document with its permissions to the object store doc.getProperties().putValue("DocumentTitle", "Example: Permissions Setting"); doc.save(RefreshMode.REFRESH); System.out.println("Document id: " + doc.get_Id().toString()); }
C# Example
// example: main snippet private void demoPermissionSetting(IObjectStore os) { //create a new permissions list IAccessPermissionList apl = Factory.AccessPermission.CreateList(); //create a new access permission object IAccessPermission ap = Factory.AccessPermission.CreateInstance(); //set access permissions ap.GranteeName = "test1"; ap.AccessType = AccessType.ALLOW; ap.AccessMask = (int) AccessLevel.FULL_CONTROL_DOCUMENT; //add the permission to the list apl.Add(ap); //Create a document and add the permissions IDocument doc = Factory.Document.CreateInstance(os, ClassNames.DOCUMENT); doc.Permissions = apl; //Save the document with its permissions to the object store doc.Properties.GetProperty("DocumentTitle").SetObjectValue("Example: Permissions Setting"); doc.Save(RefreshMode.REFRESH); System.Console.WriteLine("Document id: " + doc.Id.ToString()); }
The following code snippet retrieves all MarkingSet
objects from the FileNet® P8 domain.
Java Example
Domain domain = Factory.Domain.fetchInstance(conn, "Domain", null); domain.get_MarkingSets();
This section describes client-side implementation of Kerberos for single sign-on (SSO) authentication. For details about any Kerberos-related topic in this section, you can also refer to the Kerberos for Content Engine section of the Content Engine Administration documentation.
A number of prerequisites must be met before you can use Kerberos for single sign-on authentication. They are listed below by system, domain/account, .Net client, and Java server categories.
set JAVA_HOME=c:\j2skd1.5.0.11
%JAVA_HOME%\bin\ktab
<installation_directory>:\FileNet\ContentEngine\Kerberos\krb5.ini
. See Kerberos for Content Engine for the steps to take to modify this file for your environment.<installation_directory>:\FileNet\Content Engine\Kerberos\AllowTgtSessionKey_fix_for_Krb5LoginModule.reg
RegEdit is invoked to add a new value to the Windows system registry which disables the new security feature. This registry edit may also be used harmlessly on earlier Windows service packs.
The following is an example illustrating how to use Kerberos authentication with a Content Engine .NET API client:
Java Example
// Java clients currently do not support Kerberos authentication
C# Example
String strPrincipal = "FNCEWS/" + strHost + "@" + strDomain; SecurityToken token = new KerberosToken(strPrincipal); UserContext.SetThreadSecurityToken(token); IConnection conn = Factory.Connection.GetConnection(strURI); IDomain domain = Factory.Domain.GetInstance(conn, strP8Domain);
The above example uses the identity of the Windows system logged-on user for each Content Engine command. Note that this use is only supported when .NET 2.0 with WSE 3.0 is installed on the client system.
A pure .NET web client may also access the Content Engine by directly sending web service requests rather than making use of the Content Engine .NET API library. Here is a partial example that uses .NET 1.1 and WSE 2.0:
Java Example
// Java clients currently do not support Kerberos authentication
C# Example
CEWSI.FNCEWS35ServiceWse objBinding = new CEWSI.FNCEWS35ServiceWse(); SoapContext objCtx = objBinding.RequestSoapContext; String strPrincipal = "FNCEWS/" + strHost + "@" + strDomain; SecurityToken token = new KerberosToken2(strPrincipal); objCtx.Security.Tokens.Add(tok); ... objResponses = objBinding.GetObjects(objRequestArray); ...
When using direct web service requests, however, the KerberosToken2 object must be recreated with each web service request that is sent out and not reused or cached. If a token is reused, then there will likely be "Request is a replay" errors on the Content Engine server and the request will be rejected. (This does not apply when using the Content Engine .NET API.)
The Java and C# examples in this section show you how to work with security policies and security templates. In the examples, you'll see how to create and assign a security policy. Other examples show you how to apply an application security template to an object, and how to retrieve permission information from a security template. The last example shows you how to remove a security policy from both an object and from an object store.
The following Java and C# examples show how to create a SecurityPolicy object. To start, three SecurityTemplate
objects are created and added to a SecurityTemplateList
object. Two of the templates are of type VersioningSecurityTemplate, and one is of type ApplicationSecurityTemplate. The VersioningSecurityTemplate
objects are intended to be applied automatically to released and superseded versions of an object. The ApplicationSecurityTemplate
object must be applied to an object manually (see Applying an ApplicationSecurityTemplate). For each template, the TemplatePermissions property is set to an AccessPermissionList
object, which is returned by the setPermissions
method (not shown).
Next, a SecurityPolicy
object is created and its SecurityTemplates property is set to the SecurityTemplateList
. Note that the security policy's PreserveDirectPermissions property is set to false
; therefore, when the security policy is assigned to an object, the object's original direct permissions are replaced by the permissions defined in the security policy's templates.
Java Example
public void createSecurityObject(ObjectStore os) { // Create security templates VersioningSecurityTemplate vst1 = Factory.VersioningSecurityTemplate.createInstance(os); VersioningSecurityTemplate vst2 = Factory.VersioningSecurityTemplate.createInstance(os); ApplicationSecurityTemplate vst3 = Factory.ApplicationSecurityTemplate.createInstance(os); SecurityTemplateList stl = Factory.SecurityTemplate.createList(); vst1.set_ApplyStateID(VersionStatusId.RELEASED); vst1.set_TemplatePermissions( setPermissions("#AUTHENTICATED-USERS", AccessLevel.MAJOR_VERSION_DOCUMENT.getValue()) ); vst1.set_DisplayName("Version Template for Released Object"); vst1.set_IsEnabled(Boolean.TRUE); stl.add(vst1); vst2.set_ApplyStateID(VersionStatusId.SUPERSEDED); vst2.set_TemplatePermissions( setPermissions("#AUTHENTICATED-USERS", AccessLevel.VIEW.getValue()) ); vst2.set_DisplayName("Version Template for Superseded Object"); vst2.set_IsEnabled(Boolean.TRUE); stl.add(vst2); vst3.set_ApplyStateID(new Id("{21a47705-d20a-4b65-938e-2ddcefa45927}") ); vst3.set_TemplatePermissions( setPermissions("#AUTHENTICATED-USERS", AccessLevel.READ.getValue()+ AccessRight.DELETE_AS_INT ) ); vst3.set_DisplayName("Application Template for Obsolete Objects"); vst3.set_IsEnabled(Boolean.TRUE); stl.add(vst3); // Create security policy SecurityPolicy sp = Factory.SecurityPolicy.createInstance(os, ClassNames.SECURITY_POLICY); sp.set_SecurityTemplates(stl); sp.set_DisplayName("Security Policy with Version and Application Templates"); sp.set_PreserveDirectPermissions(Boolean.FALSE); sp.save(RefreshMode.REFRESH); }
C# Example
public void createSecurityObject(IObjectStore os) { // Create security templates IVersioningSecurityTemplate vst1 = Factory.VersioningSecurityTemplate.CreateInstance(os); IVersioningSecurityTemplate vst2 = Factory.VersioningSecurityTemplate.CreateInstance(os); IApplicationSecurityTemplate vst3 = Factory.ApplicationSecurityTemplate.CreateInstance(os); ISecurityTemplateList stl = Factory.SecurityTemplate.CreateList(); vst1.ApplyStateID = VersionStatusId.RELEASED; vst1.TemplatePermissions = setPermissions("#AUTHENTICATED-USERS", (int) AccessLevel.MAJOR_VERSION_DOCUMENT); vst1.DisplayName = "Version Template for Released Object"; vst1.IsEnabled = true; stl.Add(vst1); vst2.ApplyStateID = VersionStatusId.SUPERSEDED; vst2.TemplatePermissions = setPermissions("#AUTHENTICATED-USERS", (int) AccessLevel.VIEW); vst2.DisplayName = "Version Template for Superseded Object"; vst2.IsEnabled = true; stl.Add(vst2); vst3.ApplyStateID = new Id("{21a47705-d20a-4b65-938e-2ddcefa45927}"); vst3.TemplatePermissions = setPermissions("#AUTHENTICATED-USERS", (int) AccessLevel.READ + (int) AccessRight.DELETE); vst3.DisplayName = "Application Template for Obsolete Objects"; vst3.IsEnabled = true; stl.Add(vst3); // Create security policy ISecurityPolicy sp = Factory.SecurityPolicy.CreateInstance(os, ClassNames.SECURITY_POLICY); sp.SecurityTemplates = stl; sp.DisplayName = "Security Policy with Version and Application Templates"; sp.PreserveDirectPermissions = false; sp.Save(RefreshMode.REFRESH); }
The following Java and C# examples show how to assign a security policy to a class. The Id
objects for the ClassDefinition
and the SecurityPolicy are passed to the method, which creates the ClassDefinition
and the SecurityPolicy
objects. Using the helper method getPropertyDefinition
(not shown), the code retrieves the class's PropertyDefinition
object for SecurityPolicy, then sets it to the SecurityPolicy
object.
Note that the security policy will automatically be applied to new object instances of the class, but not to existing object instances of the class. You must explicitly set the security policy on the existing object instances of the class.
Java Example
public void assignSecurityPolicy(ObjectStore os, Id classId, Id securityPolicyId) { ClassDefinition cd = Factory.ClassDefinition.fetchInstance(os, classId, null); SecurityPolicy sp = Factory.SecurityPolicy.getInstance(os, ClassNames.SECURITY_POLICY, securityPolicyId); PropertyDefinition pd = getPropertyDefinition(cd.get_PropertyDefinitions(), ClassNames.SECURITY_POLICY); (pd.getProperties().get(PropertyNames.PROPERTY_DEFAULT_OBJECT)).setObjectValue(sp); cd.save(RefreshMode.REFRESH); }
C# Example
public void assignSecurityPolicy(IObjectStore os, Id classId, Id securityPolicyId) { IClassDefinition cd = Factory.ClassDefinition.FetchInstance(os, classId, null); ISecurityPolicy sp = Factory.SecurityPolicy.GetInstance(os, ClassNames.SECURITY_POLICY, securityPolicyId); IPropertyDefinition pd = getPropertyDefinition(cd.PropertyDefinitions, ClassNames.SECURITY_POLICY); (pd.Properties.GetProperty(PropertyNames.PROPERTY_DEFAULT_OBJECT)).SetObjectValue(sp); cd.Save(RefreshMode.REFRESH); }
The following Java and C# examples show how to apply an ApplicationSecurityTemplate to an object. The examples iterate a Folder
object, filtering all documents that have not been modified for over one year. For the documents that meet the criterion, an application security template with delete permission is applied. The examples assume that the documents in the folder were previously assigned a SecurityPolicy containing the application security template with delete permission.
Java Example
public void applyApplicationSecurityTemplate(ObjectStore os, Id folderId) { // Create folder object Folder folder = Factory.Folder.fetchInstance(os, folderId, null); // Get all documents in folder DocumentSet ds = folder.get_ContainedDocuments(); // Get current date to compare against dates of documents Calendar cal = new GregorianCalendar(); int currYear = cal.get(Calendar.YEAR); int currMonth = cal.get(Calendar.MONTH); // Iterate folder documents and check last modification date. // If over one year, apply ApplicationSecurityTemplate with delete permission. Iterator iter = ds.iterator(); while (iter.hasNext()) { Document doc = (Document) iter.next(); Date docDate = doc.get_DateLastModified(); cal.setTime(docDate); if (cal.get(Calendar.YEAR) < currYear && cal.get(Calendar.MONTH) < currMonth ) { doc.applySecurityTemplate(new Id("{21a47705-d20a-4b65-938e-2ddcefa45927}") ); doc.save(RefreshMode.REFRESH); } } }
C# Example
public void applyApplicationSecurityTemplate(IObjectStore os, Id folderId) { // Create folder object IFolder folder = Factory.Folder.FetchInstance(os, folderId, null); // Get all documents in folder IDocumentSet ds = folder.ContainedDocuments; // Get current date to compare against dates of documents int currYear = DateTime.Now.Year; int currMonth = DateTime.Now.Month; // Iterate folder documents and check last modification date. // If over one year, apply ApplicationSecurityTemplate with delete permission. System.Collections.IEnumerator iter = ds.GetEnumerator(); while (iter.MoveNext()) { IDocument doc = (IDocument) iter.Current; DateTime docDate = (DateTime) doc.DateLastModified; if (docDate.Year < currYear+1 && docDate.Month < currMonth+1) { doc.ApplySecurityTemplate(new Id("{21a47705-d20a-4b65-938e-2ddcefa45927}") ); doc.Save(RefreshMode.REFRESH); } } }
You can get descriptive permission information from a security template. A SecurityTemplate
object includes the TemplatePermissionDescriptions property, which contains a list of AccessPermissionDescription objects, from which you can get information about access rights.
The following Java and C# examples get permission descriptions for every SecurityTemplate
object contained in a
SecurityPolicy object passed to the method. Iterating the list of security templates (SecurityTemplateList
), the method retrieves the TemplatePermissionDescriptions property from a security template. It then iterates the AccessPermissionDescriptionList
and prints out information from each AccessPermissionDescription
object.
Java Example
public void getSecurityTemplateInformation(ObjectStore os, Id secPolicyId) { SecurityPolicy sp = Factory.SecurityPolicy.fetchInstance(os, secPolicyId, null ); SecurityTemplateList stl = sp.get_SecurityTemplates(); Iterator outerIter = stl.iterator(); while (outerIter.hasNext()) { SecurityTemplate st = (SecurityTemplate) outerIter.next(); AccessPermissionDescriptionList apdl = st.get_TemplatePermissionDescriptions(); Iterator innerIter = apdl.iterator(); System.out.println("Security template is " + st.get_DisplayName()); while (innerIter.hasNext()) { AccessPermissionDescription apd = (AccessPermissionDescription) innerIter.next(); System.out.println("Permission is " + apd.get_DescriptiveText() + "\n" + "Permission type is " + apd.get_PermissionType().toString() + "\n" + "Access mask is " + apd.get_AccessMask() ); } System.out.println("=============================\n"); } }
C# Example
public void getSecurityTemplateInformation(IObjectStore os, Id secPolicyId) { ISecurityPolicy sp = Factory.SecurityPolicy.FetchInstance(os, secPolicyId, null); ISecurityTemplateList stl = sp.SecurityTemplates; System.Collections.IEnumerator outerIter = stl.GetEnumerator(); while (outerIter.MoveNext()) { ISecurityTemplate st = (ISecurityTemplate) outerIter.Current; IAccessPermissionDescriptionList apdl = st.TemplatePermissionDescriptions; System.Collections.IEnumerator innerIter = apdl.GetEnumerator(); System.Console.WriteLine("Security template is " + st.DisplayName); while (innerIter.MoveNext()) { IAccessPermissionDescription apd = (IAccessPermissionDescription) innerIter.Current; System.Console.WriteLine("Permission is " + apd.DescriptiveText + "\n" + "Permission type is " + apd.PermissionType.ToString() + "\n" + "Access mask is " + apd.AccessMask ); } System.Console.WriteLine("=============================\n"); } }
You can remove a security policy from an object by setting the object's SecurityPolicy property to null
. If the object is a class, you set the class's PropertyDefinition
object for SecurityPolicy to null
. You can also remove a security policy from an object store — if no objects hold a reference to it.
The following Java and C# examples first show how to remove a security policy from a class, and then how to delete the security policy from an object store. Note that removing a security policy from a class does not remove the security policy from objects based on that class. Before you can delete a security policy from an object store, you must explicitly remove the security policy from every object that holds a reference to it.
Java Example
public void removeSecurityObject(Id classId, ObjectStore os) { // Get class from which security object will be removed. ClassDefinition cd = Factory.ClassDefinition.fetchInstance(os, classId, null); // Get property definition for SecurityPolicy. // Helper method getPropertyDefinition not shown. PropertyDefinition pd = getPropertyDefinition(cd.get_PropertyDefinitions(), ClassNames.SECURITY_POLICY); // Get Id of SecurityObject to be removed. SecurityPolicy spTarget = (SecurityPolicy) (pd.getProperties().get(PropertyNames.PROPERTY_DEFAULT_OBJECT)).getObjectValue(); Id spTargetId = spTarget.get_Id(); // Remove SecurityObject from the class. (pd.getProperties().get(PropertyNames.PROPERTY_DEFAULT_OBJECT)).setObjectValue(null); cd.save(RefreshMode.REFRESH); // Delete SecurityObject from the object store. SecurityPolicySet sps = os.get_SecurityPolicies(); Iterator outerIter = sps.iterator(); while (outerIter.hasNext()) { SecurityPolicy sp = (SecurityPolicy) outerIter.next(); if (sp.get_Id().equals(spTargetId) ) { sp.delete(); sp.save(RefreshMode.REFRESH); } } }
C# Example
public void removeSecurityObject(Id classId, IObjectStore os) { // Get class from which security object will be removed. IClassDefinition cd = Factory.ClassDefinition.FetchInstance(os, classId, null); // Get property definition for SecurityPolicy. // Helper method getPropertyDefinition not shown. IPropertyDefinition pd = getPropertyDefinition(cd.PropertyDefinitions, ClassNames.SECURITY_POLICY); // Get Id of SecurityObject to be removed. ISecurityPolicy spTarget = (ISecurityPolicy)(pd.Properties.GetProperty(PropertyNames.PROPERTY_DEFAULT_OBJECT)).GetObjectValue(); Id spTargetId = spTarget.Id; // Remove SecurityObject from the class. (pd.Properties.GetProperty(PropertyNames.PROPERTY_DEFAULT_OBJECT)).SetObjectValue(null); cd.Save(RefreshMode.REFRESH); // Delete SecurityObject from the object store. ISecurityPolicySet sps = os.SecurityPolicies; System.Collections.IEnumerator outerIter = sps.GetEnumerator(); while (outerIter.MoveNext()) { ISecurityPolicy sp = (ISecurityPolicy)outerIter.Current; if (sp.Id.Equals(spTargetId)) { sp.Delete(); sp.Save(RefreshMode.REFRESH); } } }