NIH | National Cancer Institute | NCI Wiki  

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  1. Alter Service Context(s) within Introduce
    • Modify each service context accordingly to add security
      1. Highlight Service Context, click Modify Service button
      2. Under Information Page, User Resource Framework Options section, check Secure
      3. Under Security Page (tab/button at top of dialogue), choose Custom
      4. Then under Secure Communication tab, check Transport Layer Security, choose Privacy for Communication Method
      5. Then under Authorization tab, select No for Client should connect anonymously AND select Enforce Authentication for Authorization Mechanism
      6. Then under Service Credentials tab, select System for Run As
    • Add Service Property to your (Main Service) context within Introduce,
      1. Select Service Properties tab, input the following values:

        Key

        Default Value

        Description

        gridServicePrincipalSeparator

        ||

        The separator used to encord the gridServicePrincipal and grid user's identity when Using the com.fiveamsolutions.nci.commons.authentication.CommonsGridLoginModule

      2. Click Add button
    • Ensure the appropriate Types are included within your grid service, if not add the types (XSDs) by doing the following:
      1. Import Data Types -> caDSR; Project: caGrid_Metadata_Models (version 1); Package gov.nih.nci.cagrid.metadata.security
    • Save your changes within Introduce (must be successful)
  2. Alter how remote services (eg, EJBs) are authenticated and authorized for each grid service request.
    As an example, create a GridSecurityJNDIServiceLocator class to authenticate using both the Grid User's Identity (eg, /O=caBIG/OU=caGrid/OU=Training/OU=Dorian/CN=coppagridtest instead of a typical remote service user. In short, you'll base your implementation off of your existing Locator (eg, JNDIServiceLocator) and replace existing occurrences with the new GridSecurityJNDIServiceLocator
    Tip
    Example GridSecurityJNDIServiceLocator implementation within COPPA PO Grid Service
    Example GridSecurityJNDIServiceLocator implementation within COPPA PO Grid Service

    See http://gforge.nci.nih.gov/svnroot/coppa/trunk/code/po-grid/src/gov/nih/nci/coppa/po/grid/remote/GridSecurityJNDIServiceLocator.java for full code

    Below is an example that demonstrates the essence of how to code it up your new GridSecurityJNDIServiceLocator class.
    Note
    titleAbout example

    CoreServicesConfiguration is the ServiceConfiguration for our (Main Service) context that you previously added a Service Property when updating your services using Introduce.

    Warning

    GridSecurityJNDIServiceLocator may not be a singleton (static) within your application as the contained InitialContext instance needs to reference the Grid Identity for the incoming request by using SecurityUtils.getCallerIdentity().

    Note

    While this is recognized as a performance hit, we've yet to figure a better way. If anyone is able to determine a better way, please let the COPPA team know team-po@5amsolutions.com --thanks

    Code Block
    java
    java
    titleEssentials for a GridSecurityJNDIServiceLocator implementation
    ...
        private InitialContext context;
        private static final String JNDI_PRINCIPAL = "java.naming.security.principal";
        private static final String JNDI_CREDENTIALS = "java.naming.security.credentials";
    
        /**
         * @return a ServiceLocator with the caller's identity
         * @throws Exception if a problem occurs 
         */
        public static ServiceLocator newInstance() throws Exception {
            return new GridSecurityJNDIServiceLocator(SecurityUtils.getCallerIdentity());
        }
        
        /**
         * Get an instance of the service locator. specific to the grid user.
         * 
         * @param userIdentity user identity of the grid user
         */
        public GridSecurityJNDIServiceLocator(String userIdentity) {       
            try {
                Properties props = new Properties();
                props.load(GridSecurityJNDIServiceLocator.class.getClassLoader().getResourceAsStream("jndi.properties"));
    
                // set grid service principal and grid identity as java.naming.security.principal
                CoreServicesConfiguration coreConfiguration = CoreServicesConfiguration.getConfiguration();
                String principal = props.getProperty(JNDI_PRINCIPAL)
                        + coreConfiguration.getGridServicePrincipalSeparator() + userIdentity;
                props.setProperty(JNDI_PRINCIPAL, principal);
                
                LOG.debug("Properties " + props.toString());
                
                context = new InitialContext(props);
                
            } catch (Exception e) {
                LOG.error("Unable to load jndi properties.", e);
                throw new RuntimeException("Unable to load jndi properties.", e);
            }
        }
    
    
        private Object lookup(String name) throws NamingException {
            Object object = null;
            int i = 0;
            while (object == null && i < MAX_RETRIES) {
                 try {
                     LOG.debug("Performing JNDI Lookup of : " + name);
                     object = context.lookup(name);
                 } catch (CommunicationException com) {
                     LOG.warn("Unable to lookup: " + name);
                 }
                 i++;
            }
    
            return object;
        }
    
        /**
         * {@inheritDoc}
         */
        public PersonEntityServiceRemote getPersonService() throws NamingException {
            PersonEntityServiceRemote object = (PersonEntityServiceRemote) lookup("po/PersonEntityServiceBean/remote");
            return object;
        }
    ...
    

...

This section will likely vary based on many factors and more notably your specific version of BDA and existing deployment configuration steps.

Changes to Promotion Tiers (involves Systems Team)

Warning
titleAssumptions

Grid Instance Updates

Warning

Warning: These updates only apply to the JBoss server instance that hosts new secure grid services

Overview of Updates

1. Request Host Certificates for each grid-related server instance that is to become secured.
2. Make updates to the various jboss-4.0.5.GA-jems-ejb3/server/<serverinstance>/deploy/jbossweb-tomcat55.sar/server.xml files for the JBoss server instances requiring a secure grid listener.
3. Make updates to server instance's bindings configuration (bindings.xml)
4. Ensure that OS user account has Globus available on the file system with a environment variable exported (export GLOBUS_LOCATION=<path>)

Details for specific steps (above)

...

#1.

...

Systems will need to request the host certificates for the various promotion tiers and place the generated pair of files (*-cert.pem and *-key.pem) in a location accessible to each of the various user accounts responsible for running each JBoss server instance by following the instructions here, http://cagrid.org/display/knowledgebase/Request+a+Host+CertificateImage Added. NOTE: When this is done a hostname will need to be specified which will be used by all server instances that resolve to this grid service hostname.

...

#2.

...

Information on how to update jboss-4.0.5.GA-jems-ejb3/server/<serverinstance>/deploy/jbossweb-tomcat55.sar/server.xml files
NOTE: The Grid uses it's own Trust Fabric and does not require certificates from an external Certificate Authority (CA) vendor, it includes it's own local CA and knows how to trust these certificates. This is not a standard SSL configuration.

Basically, in this step you'll be adding a HTTPS <Connector> and removing any existing HTTP & HTTPS <Connector>(s) for the <Service> definition within the bundled Tomcat servlet container inside JBoss.

In the original file you'll notice the proxyPort is set to the HTTPPort defined for the instance's specific binding configuration (see your bindings.xml) – 29080 in the example below

Code Block
titleBefore: jboss-4.0.5.GA-jems-ejb3/server/<serverinstance>/deploy/jbossweb-tomcat55.sar/server.xml

<Server>
   <Service>
   ...
     <Connector acceptCount="100" 
	  address="$\{jboss.bind.address\}" 
	  connectionTimeout="20000" 
	  disableUploadTimeout="true" 
	  emptySessionPath="true" 
	  enableLookups="false" 
	  maxHttpHeaderSize="8192"
	  maxThreads="250" 
	  port="8080" 
	  proxyName="localhost" 
	  proxyPort="29080" 
	  redirectPort="8443" 
	  strategy="ms"/>
  ...
    <Engine>
      <Host>
  ...
      </Host> 
    </Engine>
  </Service>
</Server>

Now, here is where things may get somewhat tricky (or not). To add the new Connector you'll need to remove the existing and add (define) a new <Connector>. Below is an example:

Code Block
titleAfter: jboss-4.0.5.GA-jems-ejb3/server/<serverinstance>/deploy/jbossweb-tomcat55.sar/server.xml

<Server>
   <Service>
   ...
     <Connector acceptCount="10" 
 	  autoFlush="true" 
 	  cert="/Users/smatyas/apps/po/jboss-4.0.5.GA-jems-ejb3/server/<serverinstance>/conf/<serverinstancehostname>-cert.pem" 
 	  className="org.globus.tomcat.coyote.net.HTTPSConnector" 
 	  debug="0" 
 	  disableUploadTimeout="true" 
 	  enableLookups="true" 
 	  key="/Users/smatyas/apps/po/jboss-4.0.5.GA-jems-ejb3/server/<serverinstance>/conf/<serverinstancehostname>-key.pem" 
 	  maxSpareThreads="75" 
 	  maxThreads="150" 
 	  minSpareThreads="25" 
 	  port="<DesiredPortForHTTPS>" 
 	  protocolHandlerClassName="org.apache.coyote.http11.Http11Protocol" 
 	  proxyName="<serverinstancehostname>" 
 	  proxyPort="<DesiredPortForHTTPS>" 
 	  scheme="https" 
 	  socketFactory="org.globus.tomcat.catalina.net.BaseHTTPSServerSocketFactory"/>
  ...
    <Engine>
      <Host>
  ...
      </Host> 
      <Valve className="org.globus.tomcat.coyote.valves.HTTPSValve55"/>
    </Engine>
  </Service>
</Server>

In the above example, you'll notice the absolute path to Host Cert files for the cert and key attributes. Again, these files can be anywhere on the filesystem so long as they are both accessible to the user account tied to the particular jboss server instance (jboss-4.0.5.GA-jems-ejb3/server/<serverinstance>/).
Next, you'll need to make sure you choose a <DesiredPortForHTTPS> for both the port and proxyPort attributes and that they are the same.

...

3.

...

Lastly, some changes will need to be made to the server instance bindings configuration for our instance's configuration. In short, since we've removed the existing HTTP-based <Connector> and replaced it with a HTTPS-based <Connector> we'll need to update the references to the previously defined HTTP-based port within the bindings.xml. Attached is an example bindings.xml that we've generated. You'll notice that we use 29443 throughout for our HTTPS port.
NOTE: It may be easiest, though somewhat confusing, to simply repurpose the existing HTTP port to become the HTTPS port. We choose not to do that however, that appears to be a viable option too.

...

4.

...

The binary can be found here, http://gforge.nci.nih.gov/svnroot/commonlibrary/trunk/techstack-2006/os-independent/ws-core-enum-4.0.3.zipImage Added

We recommend that the WS-CORE-4.0.3 be unpacked into a shared directory, say /usr/local/ws-core-4.0.3. Then, update the user's bash profile (~/.bash_profile) to define and export GLOBUS_LOCATION.

Code Block
titleAfter: ~/.bash_profile

ANT_HOME=/local/home/jboss45e/apache-ant-1.7.0
JAVA_HOME=/usr/jdk1.5.0_10
GLOBUS_LOCATION=/usr/local/ws-core-4.0.3

export ANT_HOME JAVA_HOME GLOBUS_LOCATION
export PATH=$ANT_HOME/bin:$JAVA_HOME/bin:$PATH