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 steps
To 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 files
This section creates a Java class that corresponds
to the PrintServiceSPISample.java file that can be located in the
[install directory]
\Adobe\Adobe LiveCycle
ES4\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 environment
To 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_Experience_Manager_forms\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 implementation
To
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.
-
Client
IP
address
:
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 permissions
You
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 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 );
}
}
Searching for events
An
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 implementation
The
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 handler
You 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 handler
To 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 handler
To 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
>
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 handler
You 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 handler
addExtAuthHandlerToPolicy(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());
}
}
|
|
|