Java SE security tutorial - Step 5

After authenticating a client, as in the previous step, you can give security privileges through eXtreme Scale authorization mechanisms.

Before you begin

Be sure to have completed Java SE security tutorial - Step 4 prior to proceeding with this task.

About this task

The previous step of this tutorial demonstrated how to enable authentication in an eXtreme Scale grid. As a result, no unauthenticated client can connect to your server and submit requests to your system. However, every authenticated client has the same permission or privileges to the server, such as reading, writing, or deleting data that is stored in the ObjectGrid maps. Clients can also issue any type of query. This section demonstrates how to use eXtreme Scale authorization to give various authenticated users varying privileges.

Similar to many other systems, eXtreme Scale adopts a permission-based authorization mechanism. WebSphere® eXtreme Scale has different permission categories that are represented by different permission classes. This topic features MapPermission. For complete category of permissions, see Client authorization programming.

In WebSphere eXtreme Scale, the com.ibm.websphere.objectgrid.security.MapPermission class represents permissions to the eXtreme Scale resources, specifically the methods of ObjectMap or JavaMap interfaces. WebSphere eXtreme Scale defines the following permission strings to access the methods of ObjectMap and JavaMap:
  • read: Grants permission to read the data from the map.
  • write: Grants permission to update the data in the map.
  • insert: Grants permission to insert the data into the map.
  • remove: Grants permission to remove the data from the map.
  • invalidate: Grants permission to invalidate the data from the map.
  • all: Grants all permissions to read, write, insert, remote, and invalidate.

The authorization occurs when a client calls a method of ObjectMap or JavaMap. The eXtreme Scale runtime environment checks different map permissions for different methods. If the required permissions are not granted to the client, an AccessControlException results.

This tutorial demonstrates how to use Java Authentication and Authorization Service (JAAS) authorization to grant authorization map accesses for different users.

Procedure

  1. Enable eXtreme Scale authorization.
    To enable authorization on the ObjectGrid, you need to set the securityEnabled attribute to true for that particular ObjectGrid in the XML file. Enabling security on the ObjectGrid means that you are enabling authorization. Use the following commands to create a new ObjectGrid XML file with security enabled.
    1. Navigate to the xml directory.
      cd objectgridRoot/xml
    2. Copy the SimpleApp.xml file to the SecureSimpleApp.xml file.
      • [Linux][Unix]
        cp SimpleApp.xml SecureSimpleApp.xml
      • [Windows]
        copy SimpleApp.xml SecureSimpleApp.xml
    3. Open the SecureSimpleApp.xml file and add securityEnabled="true" on the ObjectGrid level as the following XML shows:
      <?xml version="1.0" encoding="UTF-8"?>
      <objectGridConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
          xsi:schemaLocation="http://ibm.com/ws/objectgrid/config ../objectGrid.xsd" 
      		 xmlns="http://ibm.com/ws/objectgrid/config">
          <objectGrids>
              <objectGrid name="accounting" securityEnabled="true">
                  <backingMap name="customer" readOnly="false" copyKey="true"/>
              </objectGrid>
          </objectGrids>
      </objectGridConfig>
      
  2. Define the authorization policy.
    In the previous client authentication topic, you created the users, cashier and manager, in the keystore. In this example, the user "cashier" only has read permissions to all the maps, and the user "manager" has all permissions.
    JAAS authorization is used in this example. You must create a JAAS authorization policy file to grant permissions to principals. Create the following og_auth.policy file in the objectgridRoot/security directory:
    og_auth.policy
    grant codebase "http://www.ibm.com/com/ibm/ws/objectgrid/security/PrivilegedAction"
        principal javax.security.auth.x500.X500Principal "CN=cashier,O=acme,OU=OGSample" {
        permission com.ibm.websphere.objectgrid.security.MapPermission "accounting.*", "read";
    };
    
    grant codebase "http://www.ibm.com/com/ibm/ws/objectgrid/security/PrivilegedAction"
        principal javax.security.auth.x500.X500Principal "CN=manager,O=acme,OU=OGSample" {
        permission com.ibm.websphere.objectgrid.security.MapPermission "accounting.*", "all";
    };
    Note:
    • The codebase "http://www.ibm.com/com/ibm/ws/objectgridRoot/security/PrivilegedAction" is a specially-reserved URL for ObjectGrid. All ObjectGrid permissions granted to principals should use this special code base.
    • The first grant statement grants "read" map permission to principal "CN=cashier,O=acme,OU=OGSample", so the cashier has only map read permission to all the maps in the ObjectGrid accounting.
    • The second grant statement grants "all" map permission to principal "CN=manager,O=acme,OU=OGSample", so the manager has all permissions to maps in the ObjectGrid accounting.
    Now you can launch a server with an authorization policy. The JAAS authorization policy file can be set using the standard -D property: -Djava.security.policy=../security/og_auth.policy
  3. Run the application.

    After you create the above files, you can run the application.

    Use the following commands to start the catalog server. For more information about starting the catalog service, see Starting a stand-alone catalog service that uses the ORB transport.

    1. Navigate to the bin directory: cd objectgridRoot/bin
    2. Start the catalog server.
      • [Linux][Unix]
        ./startOgServer.sh catalogServer 
        -clusterSecurityFile ../security/security.xml 
        -serverProps ../security/server.properties 
        -jvmArgs -Djava.security.auth.login.config="../security/og_jaas.config"
      • [Windows]
        startOgServer.bat catalogServer 
        -clusterSecurityFile ..\security\security.xml 
        -serverProps ..\security\server.properties 
        -jvmArgs -Djava.security.auth.login.config="..\security\og_jaas.config"
      • [Version 8.6 and later] [Linux][Unix]
        ./startXsServer.sh catalogServer 
        -clusterSecurityFile ../security/security.xml 
        -serverProps ../security/server.properties 
        -jvmArgs -Djava.security.auth.login.config="../security/og_jaas.config"
      • [Version 8.6 and later] [Windows]
        startXsServer.bat catalogServer 
        -clusterSecurityFile ..\security\security.xml 
        -serverProps ..\security\server.properties 
        -jvmArgs -Djava.security.auth.login.config="..\security\og_jaas.config"

      The security.xml and server.properties files were created in the previous step of this tutorial.

    3. You can then start a secure container server using the following script. Run the following script from the bin directory:
      • [Linux][Unix]
        ./startOgServer.sh c0 -objectGridFile ../xml/SecureSimpleApp.xml 
        -deploymentPolicyFile ../xml/SimpleDP.xml 
        -catalogServiceEndPoints localhost:2809 
        -serverProps ../security/server.properties 
        -jvmArgs -Djava.security.auth.login.config="../security/og_jaas.config" 
        -Djava.security.policy="../security/og_auth.policy"
      • [Windows]
        startOgServer.bat c0 -objectGridFile ..\xml\SecureSimpleApp.xml 
        -deploymentPolicyFile ..\xml\SimpleDP.xml 
        -catalogServiceEndPoints localhost:2809 
        -serverProps ..\security\server.properties 
        -jvmArgs -Djava.security.auth.login.config="..\security\og_jaas.config" 
        -Djava.security.policy="..\security\og_auth.policy"
      • [Version 8.6 and later] [Linux][Unix]
        ./startXsServer.sh c0 -objectGridFile ../xml/SecureSimpleApp.xml 
        -deploymentPolicyFile ../xml/SimpleDP.xml 
        -catalogServiceEndPoints localhost:2809 
        -serverProps ../security/server.properties 
        -jvmArgs -Djava.security.auth.login.config="../security/og_jaas.config" 
        -Djava.security.policy="../security/og_auth.policy"
      • [Version 8.6 and later] [Windows]
        startXsServer.bat c0 -objectGridFile ..\xml\SecureSimpleApp.xml 
        -deploymentPolicyFile ..\xml\SimpleDP.xml 
        -catalogServiceEndPoints localhost:2809 
        -serverProps ..\security\server.properties 
        -jvmArgs -Djava.security.auth.login.config="..\security\og_jaas.config" 
        -Djava.security.policy="..\security\og_auth.policy"
    Notice the following differences from the previous container server start command:
    • The SecureSimpleApp.xml file is used instead of SimpleApp.xml file, which is the result of your running the sample sec_sample.jar file to set client authentication.
    • Another -Djava.security.policy argument was added to set the JAAS authorization policy file to the container server process.
    Use the same command as in the previous step of the tutorial:
    1. Navigate to the bin directory.
      • [Linux][Unix]
        java -classpath ../lib/objectgrid.jar:../applib/sec_sample.jar com.ibm.websphere.objectgrid.security.sample.guide.SecureSimpleApp 
        ../security/client.properties manager manager1
      • [Windows]
        java -classpath ..\lib\objectgrid.jar;..\applib\sec_sample.jar com.ibm.websphere.objectgrid.security.sample.guide.SecureSimpleApp
         ..\security\client.properties manager manager1
    2. Because user "manager" has all permissions to maps in the accounting ObjectGrid, the application runs properly.

      Now, instead of using user "manager", use user "cashier" to launch the client application.

    3. Navigate to the bin directory.
      • [Linux][Unix]
        java -classpath ../lib/objectgrid.jar:../applib/sec_sample.jar com.ibm.ws.objectgrid.security.sample.guide.SecureSimpleApp 
        ../security/client.properties cashier cashier1
      • [Windows]
        java -classpath ..\lib\objectgrid.jar;..\applib\sec_sample.jar com.ibm.ws.objectgrid.security.sample.guide.SecureSimpleApp 
        ..\security\client.properties cashier cashier1

    The following exception results:

    Attention: In the following example, some lines of code are continued on the next line for publication purposes.
    Exception in thread "P=387313:O=0:CT" com.ibm.websphere.objectgrid.TransactionException: 
    rolling back transaction, see caused by exception
    	at com.ibm.ws.objectgrid.SessionImpl.rollbackPMapChanges(SessionImpl.java:1422)
     	at com.ibm.ws.objectgrid.SessionImpl.commit(SessionImpl.java:1149)
     	at com.ibm.ws.objectgrid.SessionImpl.mapPostInvoke(SessionImpl.java:2260)
     	at com.ibm.ws.objectgrid.ObjectMapImpl.update(ObjectMapImpl.java:1062)
     	at com.ibm.ws.objectgrid.security.sample.guide.SimpleApp.run(SimpleApp.java:42)
    	at com.ibm.ws.objectgrid.security.sample.guide.SecureSimpleApp.main(SecureSimpleApp.java:27)
    Caused by: com.ibm.websphere.objectgrid.ClientServerTransactionCallbackException: 
       Client Services - received exception from remote server:
         com.ibm.websphere.objectgrid.TransactionException: transaction rolled back, 
    			see caused by Throwable
            at com.ibm.ws.objectgrid.client.RemoteTransactionCallbackImpl.processReadWriteResponse(
                RemoteTransactionCallbackImpl.java:1399)
            at com.ibm.ws.objectgrid.client.RemoteTransactionCallbackImpl.processReadWriteRequestAndResponse(
                RemoteTransactionCallbackImpl.java:2333)
            at com.ibm.ws.objectgrid.client.RemoteTransactionCallbackImpl.commit(RemoteTransactionCallbackImpl.java:557)
            at com.ibm.ws.objectgrid.SessionImpl.commit(SessionImpl.java:1079)
            ... 4 more
    Caused by: com.ibm.websphere.objectgrid.TransactionException: transaction rolled back, see caused by Throwable
            at com.ibm.ws.objectgrid.ServerCoreEventProcessor.processLogSequence(ServerCoreEventProcessor.java:1133)
            at com.ibm.ws.objectgrid.ServerCoreEventProcessor.processReadWriteTransactionRequest
    					(ServerCoreEventProcessor.java:910)
            at com.ibm.ws.objectgrid.ServerCoreEventProcessor.processClientServerRequest(ServerCoreEventProcessor.java:1285)
    
            at com.ibm.ws.objectgrid.ShardImpl.processMessage(ShardImpl.java:515)
            at com.ibm.ws.objectgrid.partition.IDLShardPOA._invoke(IDLShardPOA.java:154)
            at com.ibm.CORBA.poa.POAServerDelegate.dispatchToServant(POAServerDelegate.java:396)
            at com.ibm.CORBA.poa.POAServerDelegate.internalDispatch(POAServerDelegate.java:331)
            at com.ibm.CORBA.poa.POAServerDelegate.dispatch(POAServerDelegate.java:253)
            at com.ibm.rmi.iiop.ORB.process(ORB.java:503)
            at com.ibm.CORBA.iiop.ORB.process(ORB.java:1553)
            at com.ibm.rmi.iiop.Connection.respondTo(Connection.java:2680)
            at com.ibm.rmi.iiop.Connection.doWork(Connection.java:2554)
            at com.ibm.rmi.iiop.WorkUnitImpl.doWork(WorkUnitImpl.java:62)
            at com.ibm.rmi.iiop.WorkerThread.run(ThreadPoolImpl.java:202)
            at java.lang.Thread.run(Thread.java:803)
    Caused by: java.security.AccessControlException: Access denied (
       com.ibm.websphere.objectgrid.security.MapPermission accounting.customer write)
            at java.security.AccessControlContext.checkPermission(AccessControlContext.java:155)
            at com.ibm.ws.objectgrid.security.MapPermissionCheckAction.run(MapPermissionCheckAction.java:141)
            at java.security.AccessController.doPrivileged(AccessController.java:275)
            at javax.security.auth.Subject.doAsPrivileged(Subject.java:727)
            at com.ibm.ws.objectgrid.security.MapAuthorizer$1.run(MapAuthorizer.java:76)
            at java.security.AccessController.doPrivileged(AccessController.java:242)
            at com.ibm.ws.objectgrid.security.MapAuthorizer.check(MapAuthorizer.java:66)
            at com.ibm.ws.objectgrid.security.SecuredObjectMapImpl.checkMapAuthorization(SecuredObjectMapImpl.java:429)
            at com.ibm.ws.objectgrid.security.SecuredObjectMapImpl.update(SecuredObjectMapImpl.java:490)
            at com.ibm.ws.objectgrid.SessionImpl.processLogSequence(SessionImpl.java:1913)
            at com.ibm.ws.objectgrid.SessionImpl.processLogSequence(SessionImpl.java:1805)
            at com.ibm.ws.objectgrid.ServerCoreEventProcessor.processLogSequence(ServerCoreEventProcessor.java:1011)
            ... 14 more

    This exception occurs because the user "cashier" does not have write permission, so it cannot update the map customer.

    Now your system supports authorization. You can define authorization policies to grant different permissions to different users. For more information about authorization, see Authorizing application clients.

What to do next

Complete the next step of the tutorial. See Java SE security tutorial - Step 6.