Authorization using SAF role mapping

Mapping Java™ EE roles to users and groups can be achieved in different ways. In distributed systems, a basic registry or LDAP registry would typically be used in conjunction with an application specific <application-bnd> element, to map users from those registries into roles. The deployment descriptor of the application determines which roles can access which parts of the application.

About this task

On z/OS®, there is an additional registry type, the System Authorization Facility (SAF) registry. A Liberty JVM server implicitly uses this type for authentication when the cicsts:security-1.0 feature is installed unless configured to use LDAP. You can choose to make use of SAF authorization. When using SAF authorization, user to role mappings are used to map roles to EJBROLE resource profiles using the SAF role mapper. The server queries SAF to determine if the user has the required READ access to the EJBROLE resource profile.

In a Liberty JVM server, if you want to use Java EE roles without SAF authorization, you cannot use CICS® bundles to install your applications. This is because a CICS bundle installed application automatically creates an <application-bnd> element and uses the ALL_AUTHENTICATED_USERS special-subject, which prevents you from defining the element yourself. Instead, you must create an <application> element in server.xml directly and configure the <application-bnd> with the roles and users you require.

If, however, you choose to use Java EE roles and SAF authorization, you can continue to use CICS bundles to lifecycle your web applications. The <application-bnd> is ignored by Liberty in favor of using the role mappings determined by the SAF registry. Role mappings are determined by virtue of a user belonging to an EJB role.

Tip: When SAF authorization is enabled, EJB roles in RACF are used for role mapping instead of the roles in server.xml. Therefore, special subjects such as ALL_AUTHENTICATED_USERS and EVERYONE, or users can not be defined in server.xml in this case.
Tip: It is advisable to create or update your EJB roles before starting the CICS region. Liberty issues a RACROUTE REQUEST=LIST with GLOBAL=NO in order to support a minimum version of z/OS. The address space will not see updates until it is restarted (or started).

Procedure

  1. Add the <safAuthorization id="saf"/> element to your server.xml. If you are using the cicsts:distributedIdentity-1.0 feature, this is defined for you.
  2. Optional: You can add racRouteLog="ASIS" to the element in the previous step.
    This allows you to see the RACF® EJBROLE logging from Liberty.
  3. Create the EJB roles in RACF, with reference to the prefix scheme described.
  4. Add users to those EJB roles.

    By default, if SAF authorization is used, the application uses the pattern <profile_prefix>.<resource>.<role> to determine if a user is in a role. The profile_prefix defaults to BBGZDFLT but can be modified using the <safCredentials> element. For example, you can set it to the APPL_ID of a region. If you want multiple regions to share identical security configuration, you can set <profile_prefix> to the same value for those regions. For more information, see Accessing z/OS security resources using WZSSAD.

    The role mapping preferences can be modified using the <safRoleMapper> element in the server.xml, for example:
    <safRoleMapper profilePattern="myprofile.%resource%.%role%" toUpperCase="true"/>
    Users can then be authorized to a particular EJB role using the following RACF commands, where WEBUSER is the authenticated user ID.
    RDEFINE EJBROLE BBGZDFLT.MYAPP.ROLE UACC(NONE) 
    PERMIT BBGZDFLT.MYAPP.ROLE CLASS(EJBROLE) ACCESS(READ) ID(WEBUSER) 
  5. Optional: If you are deploying the CICS servlet examples and want to use the Java EE role security with SAF authorization, create a SAF EJBROLE for each servlet that you have deployed. For example, if you use the default APPL class of BBGZDFLT, define the following EJBROLE security definitions using RACF commands:
    RDEFINE EJBROLE BBGZDFLT.com.ibm.cics.server.examples.wlp.hello.war.cicsAllAuthenticated UACC(NONE)
    RDEFINE EJBROLE BBGZDFLT.com.ibm.cics.server.examples.wlp.tsq.app.cicsAllAuthenticated UACC(NONE)
    RDEFINE EJBROLE BBGZDFLT.com.ibm.cics.server.examples.wlp.jdbc.app.cicsAllAuthenticated UACC(NONE)
    SETROPTS RACLIST(EJBROLE) REFRESH

    Give read access to the defined roles for each web user ID that requires authorization:

    PERMIT BBGZDFLT.com.ibm.cics.server.examples.wlp.hello.war.cicsAllAuthenticated 
           CLASS(EJBROLE) ID(user) ACCESS(READ)
    PERMIT BBGZDFLT.com.ibm.cics.server.examples.wlp.tsq.app.cicsAllAuthenticated 
           CLASS(EJBROLE) ID(user) ACCESS(READ)
    PERMIT BBGZDFLT.com.ibm.cics.server.examples.wlp.jdbc.app.cicsAllAuthenticated 
           CLASS(EJBROLE) ID(user) ACCESS(READ)
    SETROPTS RACLIST(EJBROLE) REFRESH

Results

You can authorize access to web applications using CICS Security, Java EE role security, or both by defining the roles and the users in the roles.