You can create external authorization handlers
for the Rights Management service. External authorization handlers
provide centralized access control for documents in your organization.
The Rights Management service controls access to policy-protected
documents by performing a policy evaluation when determining whether
a user can access a policy-protected document. For example, the Rights
Management service decides whether a user can print a policy-protected document.
By creating an external authorization handler, you can use an
access control mechanism that your content management system uses,
in addition to the standard policy evaluation process. As a result,
document access can be controlled by the same control mechanism
that your content management system uses. For example, when the
Rights Management service determines whether a user can print a
policy-protected document, it uses the standard policy evaluation
process and the access control mechanism that your content management
system uses.
As part of the policy evaluation process, the Rights Management
service requires the identifier value of both the principal that
is requesting access to the policy-protected document and the policy-protected
document. After the Rights Management service receives these values,
it generates a set of permissions. When an external authorization
handler is registered with the Rights Management service, it passes
the set of permissions to the external authorization handler. The
external authorization handler can then add permissions to or remove
permissions from the set of permissions.
After an external authorization handler removes or adds permissions,
it returns the set of permissions and an optional expiration date
to the Rights Management service. The Rights Management service
then creates a voucher that specifies the permissions that control
access to a policy-protected document. If the voucher contains an
expiration date, then the voucher is returned to the client, where
it is stored and used. If the voucher located on the client has
expired, the Rights Management service generates the appropriate
permissions that control access to the policy-protected document.
Although it is possible to completely replace the Rights Management
service policy evaluation process with an external authorization
handler, it is recommended that you use an external authorization
handler in conjunction with the policy evaluation process.
After you deploy a component to LiveCycle, you can use it to
create a process using Workbench or you can invoke the component’s
service using an invocation method. For example, you can invoke
the service using the Java API. (See Invoking LiveCycle using the Java API.)
Note: An External Authorization Handler is a LiveCycle
component. Before you create an External Authorization Handler,
it is recommended that you become familiar with creating components.
(See Creating Your First Component.)
Summary of stepsTo develop an external authorization handler,
you must perform the following steps:
Set up your
development environment.
Define the external authorization handler implementation.
Define the component XML file.
Deploy your component.
Test your component.
Sample filesThis section creates a Java class that corresponds
to the PrintServiceSPISample.java file that can be located in the [install directory]\Adobe\Adobe LiveCycle
ES3\sdk\samples\RightsManagement\ExternalAuthorization\Java\PrintOnce
folder, where [install directory] is the LiveCycle installation location.
As you are reading through this section, it is recommended that
you also refer to this JAVA file.
Setting up your development environmentTo set up your development environment, you must create
a new Java project, such as an Eclipse project. The version of Eclipse
that is supported is 3.2.1 or later.
The Rights
Management SPI requires the edc-server-spi.jar file to be set in
your project’s class path. If you do not reference this JAR file,
you cannot use the Rights Management SPI in your Java project. This
JAR file is installed with the LiveCycle SDK in the [install directory]\Adobe\Adobe LiveCycle ES3\sdk\spi folder.
In addition to adding the edc-server-spi.jar file to your project’s
class path, you must also add the JAR files that are required to
use the Rights Management service API. These files are needed to
use the Rights Management API within the external authorization
handler. For example, you must use an EventManager object
to search for events. (See Searching for events.)
Defining the external authorization handler implementationTo
develop an external authorization handler, you must create a Java
class that implements the com.adobe.edc.server.spi.authorization.ExternalAuthorizer interface.
This class contains a method named evaluate, which
the Rights Management service invokes when a client application,
such as Acrobat, attempts to open a policy-protected document.
The evaluate method accepts a single parameter,
which is an ExternalAuthDTO object. This object
contains the following data members:
context: Specifies the context.
LicenseId: Specifies the license identifier
of the policy-protected document.
policyId: Specifies the identifier of the
policy that is protecting the document.
ClientIPaddress:
Specifies the IP address of the client that is attempting to view
the policy-protected document.
Anonymous: Specifies whether or not the
client has anonymous access to the policy-protected document.
permissions: A java.util.ArrayList object
that contains the initial permissions that were determined by the
Rights Management service’s policy evaluation process.
policyProps: A java.util.Map object
that describes policy properties. Each policy can be a single string
or an array of strings.
operationType: An ExternalAuthOperationType object
that represents an operation.
locale: A string value that specifies the
locale of the policy-protected document.
alternateId: A string value that specifies
the alternate identifier of the policy-protected document.
The evaluate method returns an ExternalAuthResultDTO object
that contains the following information:
A java.util.ArrayList object that contains
the permissions that are applied to the policy-protected document.
An expiration key that specifies the time at which the voucher
expires. If an expiration time is not specified, the voucher is
considered a one-time-only voucher that is used only for the current
operation.
Unless a policy-protected document has been revoked, an external
authorization handler is invoked, regardless of the permissions
that are returned by the policy evaluation process. Sometimes the
policy evaluation process determines that access to a policy-protected
document is denied. In this situation, the set of permissions passed
within the java.util.Map object is a zero-length
string array.
Retrieving permissionsYou
can retrieve the permissions that the Rights Management service’s
policy evaluation process generated and passed to the external authorization
handler. To retrieve permissions, invoke the ExternalAuthDTO object’s getPermissions method,
which returns a java.util.ArrayList that contains
the permissions.
//Get the permissions passed to the external authorization handler
ArrayList permissions = (ArrayList)auth_info.getPermissions();
The following table specifies the permissions that can be passed
to the an external authorization handler:
Permission Name
|
Description
|
pdrl-ex:com.adobe.aps.onlineOpen
|
Enables the document to be opened while
online.
|
pdrl-ex:com.adobe.aps.offlineOpen
|
Enables the document to be opened while
offline.
|
pdrl-ex:com.adobe.aps.revoke
|
Enables the document to be revoked.
|
pdrl-ex:com.adobe.aps.policySwitch
|
Enables a policy change on the document.
|
pdrl-ex:com.adobe.aps.pdf.printHigh
|
Enables the document to be printed at high
resolution.
|
pdrl-ex:com.adobe.aps.pdf.printLow
|
Enables the document to be printed.
|
pdrl-ex:com.adobe.aps.pdf.edit
|
Enables the document to be edited. For example,
if the PDF document is an interactive form, you can modify the document’s
fields.
|
pdrl-ex:com.adobe.aps.pdf.docAssembly
|
Enables the document to be assembled using
the Assembler service.
|
pdrl-ex:com.adobe.aps.pdf.editNotes
|
Enables comments to be applied to the document.
|
pdrl-ex:com.adobe.aps.pdf.fillAndSign
|
Enables the document to be signed.
|
pdrl-ex:com.adobe.aps.pdf.copy
|
Enables the document’s contents to be copied.
|
pdrl-ex:com.adobe.aps.pdf.accessible
|
Enables the document to be assessable using
accessible software.
|
After you retrieve the permissions that were passed to the external
authorization handler, you can either remove permissions or add
new permissions. For example, to add a permission, you can invoke
the java.util.ArrayList object’s add method.
The following code example removes the print permission. That is,
all permissions except for the print permission are added to the java.util.ArrayList object.
Retrieving permissionsprivate ArrayList removePrintFromPermissions( ArrayList permissions_list )
{
ArrayList ret_val = new ArrayList();
for( int i = 0; i < permissions_list.size(); i++ )
{
String current_permission = (String)permissions_list.get(i);
if( !( current_permission.indexOf( "print" ) >= 0 ) )
{
ret_val.add( current_permission );
}
}
Searching for eventsAn
external authorization handler can search the Rights Management
database and query information that specifies the number of times
a user performed a specific operation during a specified time interval.
For example, an external authorization handler can query the database
to determine how many times a policy-protected document has been
printed since midnight. (See Searching for Events.)
To query the Rights Management service database, invoke the EventManager object’s searchForEvents method
and pass an EventSearchFilter object. You can specify
the search criteria, such as the event name, by invoking methods
that belong to the EventSearchFilter object, as
shown in the following code example.
Searching for events EventSearchFilter print_search = new EventSearchFilter();
// Configure an event search for the print event.
print_search.setDocumentId( license_id );
print_search.setEventNamespace( "com.adobe.edc.documentevent" );
print_search.setEventName( "Print High Resolution" );
print_search.setFirstTime( new Date( 100, 1, 1 ) );
print_search.setLastTime( new Date( ) );
print_search.setWasAllowed( new Boolean(true) );
print_search.setUserOid( user_id );
Event[] out_events = _evt_manager.searchForEvents( print_search, 10 );
The searchForEvents method
returns an array of com.adobe.livecycle.rightsmanagement.client.infomodel.Event objects
matching the search filter. Before you can query the Rights Management
database, you must set connection properties. (See Setting connection properties.)
Defining the external authorization handler implementationThe
following external authorization handler implementation enables
a policy-protected document to be printed only once.
package com.adobe.livecycle.samples.externalauthorization.provider;
import com.adobe.edc.server.spi.authorization.*;
import com.adobe.idp.Context;
import com.adobe.idp.dsc.clientsdk.ServiceClientFactory;
import com.adobe.livecycle.rightsmanagement.client.RightsManagementClient;
import com.adobe.livecycle.rightsmanagement.client.EventManager;
import com.adobe.livecycle.rightsmanagement.client.infomodel.Event;
import com.adobe.livecycle.rightsmanagement.client.infomodel.EventSearchFilter;
import java.util.ArrayList;
import java.util.Date;
/**
* The PrintServiceSPISample allows a given policy-protected document to be printed only once.
*/
public class PrintServiceSPISample implements ExternalAuthorizer
{
private EventManager _evt_manager = null;
private ServiceClientFactory _sc_factory = null;
private RightsManagementClient _rm_client = null;
public ExternalAuthPropertyDTO[] getProviderProperties()
{
return new ExternalAuthPropertyDTO[0];
}
public ExternalAuthResultDTO evaluate( ExternalAuthDTO auth_info )
{
ExternalAuthResultDTO ret_val = new ExternalAuthResultDTO();
if( auth_info.getOperationType().isOperationSecureDocument() )
{
ret_val.setPermissions( auth_info.getPermissions() );
return ret_val;
}
// Determine if the document has been printed. If so,
// remove the print permission.
System.out.println( this.getClass().getName() + ": --- VIEWING DOCUMENT WITH LICENSE ID " + auth_info.getLicenseId() );
try
{
//Set connection properties
initializeRightsManagementAPI();
//Set the user context
Context context = (Context)auth_info.getContext();
String auth_user_id = context.getAuthenticatedUser().getOid();
// If the document was printed, then reset the permissions that are
// returned to the server
// so they do not include print.
if( hasDocumentBeenPrinted( auth_info.getLicenseId(), auth_user_id ) )
{
System.out.println( this.getClass().getName() + ": --- REMOVING PRINT PERMISSION FOR DOCUMENT WITH LICENSE ID " + auth_info.getLicenseId() );
//Get the final permissions
ArrayList final_permissions = removePrintFromPermissions( auth_info.getPermissions() );
//Set the final permissions
ret_val.setPermissions(final_permissions);
}
else
{
ret_val.setPermissions( auth_info.getPermissions() );
}
}
catch( Exception e )
{
ret_val.setPermissions( auth_info.getPermissions() );
}
return ret_val;
}
//Remove print permissions
private ArrayList removePrintFromPermissions( ArrayList permissions_list )
{
ArrayList ret_val = new ArrayList();
for( int i = 0; i < permissions_list.size(); i++ )
{
String current_permission = (String)permissions_list.get(i);
if( !( current_permission.indexOf( "print" ) >= 0 ) )
{
ret_val.add( current_permission );
}
}
return ret_val;
}
//Determine if the document has been printed
private boolean hasDocumentBeenPrinted( String license_id, String user_id )
{
try
{
//Create EventSearchFilter object
EventSearchFilter print_search = new EventSearchFilter();
//Configure an event search for the print event.
print_search.setDocumentId( license_id );
print_search.setEventNamespace( "com.adobe.edc.documentevent" );
print_search.setEventName( "Print High Resolution" );
print_search.setFirstTime( new Date( 100, 1, 1 ) );
print_search.setLastTime( new Date( ) );
print_search.setWasAllowed( new Boolean(true) );
print_search.setUserOid( user_id );
System.out.println( "SEARCHING FOR PRINT EVENTS FOR DOCUMENT " + license_id + " AND USER " + user_id );
//Find print events for this policy-protected document
Event[] out_events = _evt_manager.searchForEvents( print_search, 10 );
boolean was_printed = false;
if( out_events != null )
{
int n_print_events = out_events.length;
was_printed = ( n_print_events > 0 );
if( was_printed )
{
System.out.println( "DOCUMENT WAS PRINTED: " + n_print_events + " TIMES" );
}
}
return was_printed;
}
catch( Exception e )
{
e.printStackTrace();
return false;
}
}
//Set connection properties
private void initializeRightsManagementAPI() throws Exception
{
try
{
_sc_factory = ServiceClientFactory.createInstance();
_rm_client = new RightsManagementClient( _sc_factory );
_evt_manager = _rm_client.getEventManager();
}
catch( Exception e )
{
System.out.println( this.getClass().getName() + ": --- failed to initialize Rights Management API" );
throw e;
}
}
}
Note: This Java class is saved as a JAVA
file named PrintServiceSPISample.java.
Defining the component XML file for the authorization handlerYou must define a component XML file in order to deploy
the external authorization handler component. A component XML file
exists for each component and provides metadata about the component.
The following component.xml file is used for the external authorization
handler. Notice that the service name is PrintControlSPISample and
the operation this service exposes is named evaluate.
The input parameter is com.adobe.edc.server.spi.authorization.ExternalAuthDTO and
the output value is com.adobe.edc.server.spi.authorization.ExternalAuthResultDTO.
Defining the component XML file for the external authorization handler<component xmlns="http://adobe.com/idp/dsc/component/document">
<component-id>com.adobe.livecycle.samples.externalauthorization</component-id>
<version>1.0</version>
<class-path>adobe-livecycle-client.jar edc-server-spi.jar adobe-rightsmanagement-client.jar adobe-usermanager-client.jar</class-path>
<services>
<service name="PrintControlSPISample">
<specifications>
<specification spec-id="com.adobe.edc.server.spi.authorization.ExternalAuthorizer"/>
</specifications>
<specification-version>1.0</specification-version>
<implementation-class>com.adobe.livecycle.samples.externalauthorization.provider.PrintServiceSPISample</implementation-class>
<auto-deploy category-id="Samples" service-id="PrintControlSPISample" major-version="1" minor-version="0"/>
<operations>
<operation name="evaluate">
<input-parameter name="input" type="com.adobe.edc.server.spi.authorization.ExternalAuthDTO" required="true"/>
<output-parameter name="result" type="com.adobe.edc.server.spi.authorization.ExternalAuthResultDTO"/>
</operation>
<operation name="getProviderProperties">
<output-parameter name="result" type="com.adobe.edc.server.spi.authorization.ExternalAuthPropertyDTO"/>
</operation>
</operations>
</service>
</services>
</component>
Packaging the authorization handlerTo deploy the external authorization handler to LiveCycle,
you must package your Java project into a JAR file. You must ensure
that the external JAR files on which the authorization handler’s
business logic depends, such as the edc-server-spi.jar and adobe-rightsmanagement-client.jar
files, are also included in the JAR file. As well, the component
XML file must be present. The component.xml file and external JAR
files must be located at the root of the JAR file.
The following illustration shows the Java project’s content that
is packaged into the external authorization handler’s JAR file.
You must package the external authorization handler into a JAR
file. In the previous diagram, notice that .JAVA files are listed.
Once packaged into a JAR file, the corresponding .CLASS files must
also be specified. Without the .CLASS files, the authorization handler
does not work.
Note: After you package the external authorization
handler into a JAR file, you can deploy the component to LiveCycle.
After you deploy the component, ensure that you restart the J2EE
application server on which LiveCycle is deployed. (See Deploying your component.)
Testing the authorization handlerTo test the external authorization handler, you can create
a policy that uses it. For example, if you create a policy that
uses the external authorization handler created in this section
and apply the policy to a document, you are then only able to print
the document once. That is, once you print the policy-protected document,
the print menu option is not enabled.
Note: After the document is printed, the print permission
is removed provided that the PDF document is closed and then opened
again.
After you create a policy that uses the external authorization
handler, you can secure a PDF document with the policy. (See Applying Policies to PDF Documents.)
PDF document that are secured with a policy that contains an
external authorization handler can no longer be opened when the
external authorization handler is stopped or uninstalled. When attempting
to open the PDF document, you will receive an error message and
the PDF document is not opened. You can open the PDF document by
restarting the external authorization handler (or reinstalling and
then starting it).
To create a policy that uses the external authorization handler:Deploy the external authorization handler’s JAR file using
Workbench. (See Deploying your component.)
Restart the application server.
Log in to Administration Console.
Click Services > Rights Management ES3 > Policies.
Click on a given policy set.
Click the Policies tab and click New.
In the Name field, specify a name for the policy.
In the External Authorization Providers section, click PrintControlSPISample.
Click Save. A green check mark will appear next to
the PrintControlSPISample item indicating that it is active.
Finish creating the policy and save it.
Programmatically adding an external authorization handlerYou can programmatically add an external authorization
handler to a policy by using the Rights Management Service API.
To programmatically add an external authorization handler, perform
the following tasks:
Create a Policy object. For example,
when modifying a policy, you create a Policy object.
(See Modify existing policies using the Java API.)
Invoke the Policy object’s setPolicyProperties method.
When invoking the setPolicyProperties method,
pass a java.io.Map object. The key (property name),
in the java.io.Map object is the external authorizer
handler. The following example is the key and value pair of a policy that
contains an external authorizer handler and is printed in XML format (assuming
the handler name is RemovePrintPerms):
<Property PropertyName="external authorizer"><PropertyValue>RemovePrintPerms</PropertyValue>
The following code fragment shows how to programmatically add
an external authorization handler to a policy.
Programmatically adding an external authorization handleraddExtAuthHandlerToPolicy(String handlerName)
{
try
{
// The key which will be added to the Map (the property name)
String handlerTag = "external authorizer";
Map<String,String> policyProps = new HashMap<String,String>();
policyProps.put(handlerTag, handlerName);
this.policy.setPolicyProperties(policyProps);
}
catch(Exception e)
{
fail("addExtAuthHandlerToPolicy(): The method " +
"threw an unexpected exception.\n " + e.getMessage());
}
}
|
|
|