Advanced Customization > Business Logic Customization > Customizing Security Labels > Setting Up Custom Security Labels
  
Setting Up Custom Security Labels
The following sections should be used in conjunction with the Security Labels Configuration Steps. One or all of these customizations can be completed.
* 
If you are using custom security labels, PTC recommends adding validation to the user interface if users are able to enter values manually, such as by using the text field provided by default when custom security labels are configured. A custom translator class is recommended to validate the values to prevent unexpected values from being stored in the database, either if the user enters an invalid value in the user interface or if an invalid value is specified in an import file.
Enabling Custom Security Labels
To enable custom security labels, you must complete the following steps. See the Security Labels Configuration Steps for more information about each of these steps.
1. Define Security Labels - Required
Add the following lines to the <Windchill>/wtcustom/wt/access/accessModelRB.rbinfo file, making sure not to include any spaces except in the <DISPLAY_NAME> or the <LONG_DESCRIPTION>:
WCTYPE|wt.access.SecurityLabeled~SCA|<SECURITY_LABEL>.value=<DISPLAY_NAME>
WCTYPE|wt.access.SecurityLabeled~SCA|<SECURITY_LABEL>.dataType=java.lang.String
WCTYPE|wt.access.SecurityLabeled~SCA|<SECURITY_LABEL>.serverFunction=
com.ptc.core.foundation.security.server.impl.SACFSecurityLabel
WCTYPE|wt.access.SecurityLabeled~SCA|<SECURITY_LABEL>.serverFunction.arg1=
PID{<SECURITY_LABEL>}
WCTYPE|wt.access.SecurityLabeled~SCA|<SECURITY_LABEL>.longDescription=
<LONG_DESCRIPTION>
where:
<SECURITY_LABEL> is the custom security label name. This value should use only alphanumeric characters and the underscore character. The string WCTYPE|wt.access.SecurityLabeled~SCA|<SECURITY_LABEL> is the value that will be specified for the SecurityLabelResourceKey element for the custom security label later in this configuration. While there is no requirement for the <SECURITY_LABEL> value to match the name attribute specified for the CustomSecurityLabel element in the security labels configuration file, that is the convention used in this guide.
* 
A security label name is stored as a server-calculated attribute (SCA). Each SCA must have a unique name. The Logical Attributes Report provides a list of all current SCAs. You can access this report from <Windchill>/netmarkets/jsp/lwcType/logicalAttributesReport.jsp.
<DISPLAY_NAME> is the name of the custom security label as it will display in the user interface.
<LONG_DESCRIPTION> is the long description of the custom security label. The long description is displayed in the automatically generated description for the custom security label, accessed by clicking the view security label information icon from the Security Labels table.
* 
Because custom security label values are not pre-defined, there is no long description available to display on the information page for the custom security label. Any information about the custom security label values can be included in the long description for the custom security label.
For example, add the following lines to the end of the file for configuring the example custom security label:
WCTYPE|wt.access.SecurityLabeled~SCA|THIRD_PARTY_PROPRIETARY.value=
Third Party Proprietary
WCTYPE|wt.access.SecurityLabeled~SCA|THIRD_PARTY_PROPRIETARY.dataType=
java.lang.String
WCTYPE|wt.access.SecurityLabeled~SCA|THIRD_PARTY_PROPRIETARY.serverFunction=
com.ptc.core.foundation.security.server.impl.SACFSecurityLabel
WCTYPE|wt.access.SecurityLabeled~SCA|
THIRD_PARTY_PROPRIETARY.serverFunction.arg1=
PID{THIRD_PARTY_PROPRIETARY}
WCTYPE|wt.access.SecurityLabeled~SCA|THIRD_PARTY_PROPRIETARY.longDescription=
The "Third Party Proprietary" label indicates the business object's level of third party corporate sensitivity.
* 
Do not delete or alter the existing lines that begin with:
WCTYPE|wt.access.SecurityLabeled~SCA|ALL_SECURITY_LABELS
WCTYPE|wt.access.SecurityLabeled~SCA|ALL_STANDARD_SECURITY_LABELS
WCTYPE|wt.access.SecurityLabeled~SCA|ALL_CUSTOM_SECURITY_LABELS
2. Create a Custom Java Evaluator Class - Optional
For more information about this step, see section Create a Custom Java Evaluator Class.
3. Create a Custom Java Translator Class - Optional
For more information about this step, see section Create a Custom Java Translator Class.
4. Edit the Security Labels Configuration File - Required
For more information about this step, see section Edit the Security Labels Configuration File for Custom Security Labels.
5. Edit LogicalAttributesSite.xml - Required
For more information about this step, see Edit LogicalAttributesSite.xml in the security labels configuration steps.
6. Specify Attribute Handler for Label Attribute - Required
From within a windchill shell, run the following command for each custom security label:
xconfmanager -s wt.services/svc/default/com.ptc.core.command.
server.delegate.io.AbstractAttributeHandler/
<CUSTOM_SECURITY_LABEL>
/wt.access.SecurityLabeled/
0=com.ptc.core.command.server.delegate.io.
SecurityLabelAttributeHandler/
singleton -t codebase/com/ptc/core/foundation/
FoundationAttributeHandler.properties -p
where <CUSTOM_SECURITY_LABEL> is the custom security label name as specified in the securityLabelsConfiguration.xml file.
For example, the following command would be run for the example custom security label:
xconfmanager -s wt.services/svc/default/com.ptc.core.command. server.delegate.io.AbstractAttributeHandler/THIRD_PARTY_PROPRIETARY /wt.access.SecurityLabeled/0=com.ptc.core.command.server.delegate .io.SecurityLabelAttributeHandler/singleton -t codebase/com/ ptc/core/foundation/FoundationAttributeHandler.properties -p
7. Restart Windchill method servers.
* 
Additional configuration is required to enable object initialization rules, agreements, auditing, and subscriptions for custom security labels, but the steps are the same for standard and custom security labels.
For information about enabling these additional capabilities, see the Security Labels Configuration Steps.
Create a Custom Java Evaluator Class
* 
If custom evaluation is needed when determining if a participant is restricted by a security label value, or when determining if a participant is able to modify a security label value, then a custom Java evaluator class is required.
A custom Java evaluator class can be used to determine if a participant is restricted by the security label value specified and to determine if the participant is able to modify the security label value. To do this, the class must extend the wt.access.UnrestrictedPrincipalEvaluator class.
The wt.access.UnrestrictedPrincipalEvaluator class contains four methods. Any of these methods can be overridden, depending on whether the default behavior is sufficient:
boolean isRestrictedBySecurityLabelValue(WTPrincipal principal, String label_name, String label_value) - Determines if a participant is restricted by the security label value by evaluating the participant, the security label, and the security label value.
If this method is not overridden, its default behavior evaluates the UFID provided in the security labels configuration file to determine if the participant is the user specified by the UFID or a member of the group or organization specified by the UFID. To get the default answer in your overridden method, include a call to super.isRestrictedBySecurityLabelValue(principal, label_name, label_value) in your class.
boolean isRestrictedBySecurityLabelValue(WTPrincipal principal, SecurityLabeled object, String label_name, String label_value) - Determines if a participant is restricted by the security label value by evaluating the participant, the object, the security label, and the security label value. The object could be an AccessControlSurrogate. The AccessControlSurrogate acts as a stand-in for a persistable object, and contains all the attributes Windchill needs to determine access rights without having the full persistable object. For more information about an AccessControlSurrogate, see section Handling an AccessControlSurrogate.
If this method is not overridden, its default behavior is to call the boolean isRestrictedBySecurityLabelValue(WTPrincipal principal, String label_name, String label_value) method.
boolean isAllowedToModifySecurityLabelValue(WTPrincipal principal, SecurityLabeled object, String label_name, String label_value) - Determines if a participant is allowed to modify the security label value by evaluating the participant, the security label, the security label value, and the object.
If this method is not overridden, its default behavior evaluates the UFID provided in the security labels configuration file to determine if the participant is the user specified by the UFID or a member of the group or organization specified by the UFID. To get the default answer in your overridden method, include a call to super.isAllowedToModifySecurityLabelValue(principal, object, label_name, label_value) in your class.
WTKeyedHashMap isAllowedToModifySecurityLabelValues(WTPrincipal principal, WTKeyedMap objects_to_security_labels_map) - Determines if a participant is allowed to modify specified security label / value pairs on a collection of objects. A separate Boolean result is returned for each specified combination of label, value, and object.
If this method is not overridden, its default behavior is to call the single-value evaluator, isAllowedToModifySecurityLabelValue, for each of the label/value pairs, for each of the objects. This may cause performance issues if, for example, the evaluation requires separately querying an external system for each evaluation. The custom evaluator may therefore override this method with a more efficient implementation- for example, combining calls to the external system, or caching results to avoid repetitive evaluations.
An example custom Java evaluator class can be found in the <Windchill>/prog_examples/access directory. For more information about the use case and setting up Windchill to use the example, refer to the Javadoc for the custom Java evaluator class for each of the implemented methods.
For more information about working with class files, see Managing Customizations.
Handling an AccessControlSurrogate
When Windchill access control service methods are called to evaluate a user's access rights to information, the methods may be given a persistable object or a wt.access.AccessControlSurrogate. The AccessControlSurrogate acts as a stand-in for a persistable object, to evaluate access rights for the information returned when a database query is performed requesting specific attributes of an object rather than a full persistable. The surrogate contains attributes from the class it is representing and includes all possible attributes necessary for making the access control decision.
The boolean isRestrictedBySecurityLabelValue(WTPrincipal principal, SecurityLabeled object, String label_name, String label_value) method defined by the wt.access.UnrestrictedPrincipalEvaluator class could be given an AccessControlSurrogate object. If you override this method in a custom Java evaluator class, your custom code should check if the object is an instance of AccessControlSurrogate before trying to check various attributes.
The wt.fc.ObjectIdentifier method getId() can be used to get the unique identifier of the represented persistable object. The class name in the ObjectIdentifier is wt.access.AccessControlSurrogate. The surrogate has a getTargetClassName method which can be used to get the class name of the represented persistable object. For example:
Class targetClass = Object.class;
if (object instanceof AccessControlSurrogate) {
try {
targetClass = Class.forName(((AccessControlSurrogate)
object).getTargetClassName());
}
catch (ClassNotFoundException cnfe) {
...
}
long id = PersistenceHelper.getObjectIdentifier(object).getId();
}
The attributes that are available on the AccessControlSurrogate depend on the type of the represented persistable object and whether Agreements are enabled on your system.
The following attributes are available and have supported APIs to access them.:
If the wt.admin.DomainAdministered interface is a superinterface of the target class, the wt.admin.DomainAdministeredHelper method getAdminDomainRef(DomainAdministered obj) can be used to get the object's domain reference.
If the wt.lifecycle.LifeCycleManaged interface is a superinterface of the target class, its getState() method can be used to get the object's life cycle state.
If the wt.access.SecurityLabeled interface is a superinterface of the target class, the wt.access.AccessControlManager method getSecurityLabels(SecurityLabeled object) can be used to get a map of the object's security labels and their values.
If Agreements are enabled on your system in addition to the SecurityLabeled interface being a superinterface of the target class:
If the wt.inf.container.WTContained interface is a superinterface of the target class, the wt.inf.container.WTContainerHelper method getContainer(WTContained contained) can be used to get the context of the object
If the wt.vc.Iterated interface is a superinterface of the target class, its getMasterReference() method can be used to get the ObjectReference of the iteration's master. Also, the wt.vc.VersionControlHelper method getBranchIdentifier(Iterated iteration) can be used to get the iteration's branch id
If the wt.vc.wip.Workable interface is a superinterface of the target class, the wt.vc.wip.WorkInProgressHelper method getState(Workable object) can be used to get the work-in-progress state of the object and its APIs such as isCheckedOut(Workable object), isReservedWorkingCopy(Workable object) and isPrivateWorkingCopy(Workable object) can be used to evaluate the state
Create a Custom Java Translator Class
For custom security labels a custom Java translator class can be used to convert the internal form of the security label value into the external form of the security label value or back again. To do this, the class must extend the wt.access.CustomSecurityLabelValueTranslator class. The internal form is used by Windchill during access evaluations and is stored in the database. The external form is what is displayed in the Windchill interface and what users will enter when specifying a security label value. If no translator class is defined, the external form is the same as the internal form and is what is stored in the database.
There are certain restrictions on what can be included in the internal form. The equals (=) and comma (,) characters cannot be stored in the database. If your user-entered security label values will use either of these characters, you must use a translator class to remove them from the internal name. Similarly, the string NULL cannot be stored in the database. Using a custom Java translator class also allows you to have longer security label value names. The security label attribute is limited to 4000 characters in the database, so having lengthy security label values can cause a storage issue. By specifying a custom translator class, you can have descriptive label values in the Windchill user interface using an external form and less user-friendly values stored in the database using an internal form. A custom translator class can also be used to validate custom security label values, particularly in cases where there is no user interface to validate the user-specified label values.
The wt.access.CustomSecurityLabelValueTranslator class contains two methods:
getExternalValue - Returns the external value associated with a given internal value.
getInternalValue - Returns the internal value associated with a given external value.
The following simple example removes the restricted comma character (,) and replaces it with an unrestricted plus character (+). This example assumes that the external value never contains a plus character (+).
public class CustomTranslator implements CustomSecurityLabelValueTranslator {
public String getExternalValue(String label_name, String internal_value)
throws WTException {
return internal_value.replace("+", ",");
}
public String getInternalValue(String label_name, String external_value)
throws WTException {
return external_value.replace(",", "+");
}
}
Each method must always return the same answer when given the same input. If you anticipate the internal value changing over time, consider putting a version number in the string. For example, if a custom security label represents third party companies with whom you work, you may need to add the countries in which each third party has offices at some point in the future. Initially, one external value could be “Company A”, with the internal value of “1:A”. In the future, when office locations of Company A need to be represented, the external value could change to “Company A (US)” and “Company A (UK)”. The corresponding internal values could change to “2:A-US” and “2:A-UK”. The version number can be used to let the custom translator class know how to translate each version individually since the database might have both versions stored.
For more information about working with class files, see Managing Customizations.
Edit the Security Labels Configuration File for Custom Security Labels
This information relates to the Edit the Security Labels Configuration File - Required step of the Security Labels Configuration Steps.
* 
An example illustrating the use of a custom security label can be found in the <Windchill>/conf/securityLabelsConfiguration_sample.xml file. While the sample configuration file includes sample data similar to the example configuration used in this document, actual values from your system are required to successfully configure custom security labels.
A description of the sample configuration is available in the Security Labels Example Configuration section.
To enable custom security labels, add a CustomSecurityLabel element and its subelements for each custom security label. When you are finished, save and close the file.
CustomSecurityLabel element
The CustomSecurityLabel element contains the data for defining a custom security label, the authorized participant for the custom security label values (if not all users), the agreement type (if any) associated with the custom security label values, and various mappings used by applications and services to process custom security labels. There should be one CustomSecurityLabel element for each custom security label you configure. For example:
<CustomSecurityLabel name="THIRD_PARTY_PROPRIETARY" enabled="true">
<SecurityLabelResourceKey>WCTYPE|wt.access.SecurityLabeled~SCA|
THIRD_PARTY_PROPRIETARY</SecurityLabelResourceKey>
<CustomSecurityLabelValues>
<UnrestrictedPrincipal>
<ufid>cn=Employees,cn=Public,ou=people,cn=AdministrativeLdap,
cn=Windchill_10.1,o=ptc|Ldap.ptcnet.ptc.com|
Ldap.ptcnet.ptc.com</ufid>
<evaluatorClass>
com.ourcompany.CustomEvaluator
</evaluatorClass>
</UnrestrictedPrincipal>
<TranslatorClass>
com.ourcompany.CustomTranslator
</TranslatorClass>
</CustomSecurityLabelValues>
<SecurityLabelParameter>THIRD_PARTY_PROPRIETARY
</SecurityLabelParameter>
</CustomSecurityLabel>
The name attribute of the CustomSecurityLabel element is the string that is stored in the database for this security label, in this case, THIRD_PARTY_PROPRIETARY. For this custom security label to be available in your Windchill solution, the enabled attribute must be set to true. This name value does not generally show in the user interface; the display name for this security label was defined in the <Windchill>/wtcustom/wt/access/accessModelRB.rbinfo file previously.
* 
Keep the name attribute of the CustomSecurityLabel element and the internal custom label values as short as possible. You can use the TranslatorClass element to reduce the size of the internal values stored in the database. For more information, see section Create a Custom Java Translator Class.
The SecurityLabelResourceKey element represents the resource key for the label, and is specified in the following format:
WCTYPE|wt.access.SecurityLabeled~SCA|<SECURITY_LABEL>
where <SECURITY_LABEL> is the value of the name attribute on the CustomSecurityLabel element. This resource key must be present in the accessModelRB.rbinfo resource file edited previously.
* 
Even if security labels are globally disabled, the security label resource keys specified in the configuration file must exist in the accessModelRB.rbinfo for the method server to start.
For more information on disabling security labels, see Disabling Security Labels and Values.
The CustomSecurityLabelValues element can have a single UnrestrictedPrincipal subelement, which specifies the authorized participant for the security label values. If the UnrestrictedPrincipal subelement is omitted, all users are cleared for access to objects with the custom label values.
The UnrestrictedPrincipal element can have a ufid subelement. The UFID, or Unique Federation Identifier, specifies a participant, which can be a user, user-defined group, or organization. The UnrestrictedPrincipal element can also have an evaluatorClass subelement, which specifies the evaluator class created in Create a Custom Java Evaluator Class. The ufid subelement and the evaluatorClass subelement can either be used together or individually under the UnrestrictedPrincipal element. For more information about the differences between using a ufid subelement, an evaluatorClass subelement, or both, see Specifying Authorized Participants for Custom Security Labels.
The UnrestrictedPrincipal element can optionally have an AgreementType subelement. An agreement can be used to grant temporary clearance to users who are not authorized participants for the security label values. The content for the AgreementType element is specified in the following format:
<logicalTypeId><AGREEMENT_NAME></logicalTypeId>
where <AGREEMENT_NAME> is the internal name of the agreement type or subtype.
The optional TranslatorClass element specifies the class created in section Create a Custom Java Translator Class. The TranslatorClass element converts the internal name of the security label values into the external names, which appear throughout Windchill, and back again. If the TranslatorClass element is not specified, the internal and external values for the custom security label values are the same.
The optional SecurityLabelParameter element contains the parameter name used by various authoring applications as a file attribute to map to this custom security label. SecurityLabelParameter is always the last element within the CustomSecurityLabel element. The parameter name must follow any restrictions for parameter names that exist for the authoring applications.