NIH | National Cancer Institute | NCI Wiki  

Error rendering macro 'rw-search'

null

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 10 Next »

Purpose

To provide a lightweight guide for other CBIIT applications (eg, caArray) can secure their own grid services.

Technical Details

Assumptions

  • JBoss 4.0.5
  • JAAS
  • Remote EJBs for business application integration
  • caGrid 1.3
  • Using BDA for JBoss container configuration of secure services
  • Using Common Security Module (CSM)

Changes to Business Application

Assumptions

  • JBoss 4.0.5
  • JAAS
  • Existing Secured Remote EJBs
  1. Add CommonsGridLoginModule to JAAS login module (security-config.xml)
    • (warning) requires nci-commons-core version 1.2.4 or greater see http://maven.5amsolutions.com/archiva/browse/com.fiveamsolutions/nci-commons-core
    • (warning) requires jbosssx.jar as runtime dependency to handle decryption of encrypted pre-shared key within CommonsGridLoginModule class. Typically included with JBoss by default, please verify.
      <login-module code="com.fiveamsolutions.nci.commons.authentication.CommonsGridLoginModule" flag="optional">
          <module-option name="gridServicePrincipal">${gridServicePrincipal}</module-option>
          <module-option name="gridServiceCredential">${gridServiceCredential}</module-option>
          <module-option name="gridServicePrincipalSeparator">||</module-option>
      </login-module>
      
    • Define gridServicePrincipal & gridServiceCredential properties within appropriate properties file so that the login module configuration file is properly configured as a part of the build and deployment process for your application
      Example snippet to add Maven2 properties
              <gridServicePrincipal>Gr1DU5er</gridServicePrincipal>
              <gridServiceCredential>ltHZmZ1rqYq8j2uyHEABIQ==</gridServiceCredential>
      
  2. Introduce a new grid service instance CSM Group
    (warning) Update the application name 'po' to your application's name
    Sample SQL for Postgres to define a new CSM Group
    INSERT INTO CSM_GROUP (GROUP_NAME, GROUP_DESC, APPLICATION_ID) VALUES ('gridClient', 'Grid Service Invocation Group', (select application_id from csm_application where application_name = 'po'));
    
  3. Update @Remote EJBs endpoints to allow the new CSM Group using the @RolesAllowed annotation
    @RolesAllowed("gridClient")
    public void myRemoteEndpointMethod() { ... }
    

Changes to Grid Service(s)

  1. Alter Service Context(s) within Introduce
    • Modify each service context accordingly
      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 Below is an example that demonstrates the essence of how to code it up your new GridSecurityJNDIServiceLocator class.

    About example

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

    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().

    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

    Essentials 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;
        }
    ...
    

Changes to BDA scripts

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

  • No labels