Oracle by Example brandingConfigure JWT Authentication Provider

section 0Before You Begin

This 15-minute tutorial shows you how to create and manage in a self-service manner, a JWT (JSON Web Token) allowing you to authentication both REST and SOAP calls against Oracle HCM. This authentication approach can be used instead of using Basic Authentication (Username/Password).

Background

With 20D the functionality to manage JWT within the security console is provided to customer security managers. REST and SOAP APIs are secured with various function security privileges and data security policies. These privileges and policies are delivered through predefined duty roles, which control access to person and employment objects. Depending on the roles assigned, and their level of access, users view or manage data via integration tools.

For more information on role types and their functions, see: Oracle Fusion Applications Security Guide.


section 1Generate a X.509 Key Pair

Core to the creation and management of JWT’s is the X509 key pair. This key par will be unique to your organization. There are several commercially available tools that can be used to generate X.509 key pairs. However, for the purpose of this tutorial the widely available and open source software library OpenSSL is used.

he basic command line steps to generate a private and public X509 key pair using OpenSSL are as follows:

  1. generate a private key (private.key).

    openssl genrsa -out private.key 2048
  2. Using the created private key, create an X509 certificate (.cer file) containing your public key.

    openssl req -new -x509 -key private.key -out publickey.cer -days 365

section 2Generate a JWT

Once you have successfully create your X509 key pair, you can begin the construction of you JWT In order to generate a valid JWT you are required to provide the following:

    Header The header consists of three parts:
    • The signing algorithm being used, such as HMAC SHA256 or RSA
    • The token type, which is JWT
    • The x5t which is the base64 encoded fingerprint of the trusted issuer cert. (Sourced from your newly created X509 key pair)
    Payload The second part of the token is the payload, which contains the claims. Claims are statements about an entity (typically who the user is) and any additional data. There are three types of claims: registered, public, and private claims. Using JWT with HCM requires a preset list of standards to be provided.
    Signature To create the signature part you have to take the encoded header, the encoded payload, a secret, the algorithm specified in the header, and sign that. This is used as the Message Authentication Code (MAC).

Generate the Header

The Header section is formatted as a JSON string.

    {
      "alg": "RS256",
      "typ": "JWT",
      "x5t": " AG1vSl82cRAk+PD9M4ltxeuSAA8="
    }
    

    Retrieve the Alg Value:

    The alg value is the signing algorithm of the publickey.cer created in the previous section, in this example RS256. Open the file with a certificate viewer or run the following OpenSSL command.

    openssl x509 -in publickey.cer -text -noout

    This will output all the values associated with the certificate including the Public Key Algorithm.

    Specify the Token Type:

    This will always be 'JWT'

    Retrieve the x5t or fingerprint of the trusted issuer certificate

    The x5t value is derived from the publickey.cer and can be viewed in a certificate viewer or output by running the following openssl command.

    openssl x509 -sha1 -in publickey.cer -noout -fingerprint

    The fingerprint output will be in hexadecimal:

    Fingerprint=00:6D:6F:4A:5F:36:71:10:24:F8:F0:FD:33:89:6D:C5:EB:92:00:0F

    Once the fingerprint has been retrieved, you will need to convert to base64, though some certificate viewers will display the fingerprint in both hexadecimal and base64 format. The following is the base64 output of the above hexadecimal string.

    echo "00:6D:6F:4A:5F:36:71:10:24:F8:F0:FD:33:89:6D:C5:EB:92:00:0F"|xxd -r -p | base64

    xt5 output

    AG1vSl82cRAk+PD9M4ltxeuSAA8=

    Generate the Payload

    The Payload section is also formatted as a JSON string. Oracle HCM has the requirement for the following fields and values.

    {
      "iss": "www.mycompany.com",
      "prn": "fusion",
      "iat": 1596271154,
      "exp": 1918081154
    }
    

    The payload is constructed based on the following rules.

    Abbreviation Meaning Description
    iss Issuer Default to www.mycompany.com
    prn Principal The username of user that has the Fusion Applications Integration privilege (in this example ‘fusion’)
    iat Issued At Unix epoch time format of when the token was generated e.g ‘1596271154’ for 08/01/2020 @ 8:39am (UTC)
    exp Expiration Unix epoch time format of when the token will expire e.g ‘1918081154’ for 10/13/2030 @ 12:19am (UTC)

Generate the Verify Signature

The final part of the JWT construction is the signature, which is used to verify that REST or SOAP message wasn't changed during transmission.

The signature is created by encoding the encoded header, the encoded payload, a secret, the algorithm specified in the header, and then sign. After generating the ava web token copy the encoded text and store locally. This is your JWT, and will be required for authentication with REST and SOAP calls.

Manual

Go to a website of a provider that will generate a JWT and provide the header and private keys.

Automated

  • Use thirdparty libraries such as libraries from https://jwt.io/
  • use oracle -Oracle Security Developer Tools(shipped with weblogic,can be downloaded from OTN) https://docs.oracle.com/cd/E23943_01/security.1111/e10037/jwt.htm#CIHCEHJJ

Steps

  1. Create a directory /tmp/src
  2. copy below code as GenerateJWT.java

    import oracle.security.restsec.jwt.JwtToken;
    import java.io.FileInputStream;
    import java.io.InputStream;
    import java.io.RandomAccessFile;
    import java.util.Date;
    import java.security.KeyFactory;
    import java.security.PrivateKey;
    import java.security.cert.CertificateFactory;
    import java.security.cert.X509Certificate;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.MessageDigest;
     
    public class GenerateJWT
    {       public static void main(String[] args) throws Exception
            {
                    String iss ="www.mycompany.com"; //JWT issuer -iss attribute
                    String prn="fusion"; //JWT principalll -prn attribute
                    JwtToken jwtToken = new JwtToken();
                    //Fill in all the parameters- algorithm, issuer, expiry time, other claims etc
     
                    jwtToken.setAlgorithm(JwtToken.SIGN_ALGORITHM.RS256.toString());
                    jwtToken.setIssuer(iss);
                    jwtToken.setPrincipal(prn);
                    jwtToken.setType(JwtToken.JWT);
                    jwtToken.setClaimParameter("tenant","123456"); //this will set custom claim parameters,example "tenant" is custom JWT claim with value "123456")
                    //iat attribute-time when JWT was generated
                    long nowMillis = System.currentTimeMillis();
                    Date now = new Date(nowMillis);
                    jwtToken.setIssueTime(now);
                    //token expires in 10 minutes
                    jwtToken.setExpiryTime(new Date(nowMillis + 10*60*1000));
     
                    //x5t attribute,read the public key from pem format
                    InputStream inStream = new FileInputStream("pub.pem");
                    CertificateFactory cf = CertificateFactory.getInstance("X.509");
                    X509Certificate publicKey = (X509Certificate)cf.generateCertificate(inStream);
                    inStream.close();
                    jwtToken.setX509CertThumbprint(publicKey);
     
                    //for signing read private key in der format
                    RandomAccessFile raf = new RandomAccessFile("jwt.der", "r");
                    byte[] buf = new byte[(int)raf.length()];
                    raf.readFully(buf);
                    raf.close();
                    PKCS8EncodedKeySpec kspec = new PKCS8EncodedKeySpec(buf);
                    KeyFactory kf = KeyFactory.getInstance("RSA");
                    PrivateKey privateKey = kf.generatePrivate(kspec);
     
                    // sign the token with a private key
                    String jwtString = jwtToken.signAndSerialize(privateKey);
                    System.out.println(jwtString);
            }
    }
  3. for signing convert Pem private key(from top of the confluenc) to Der format or use JKS,also copy the publickey into pub.pem file,copy both files to /tmp/src

    openssl pkcs8 -topk8 -inform PEM -outform DER -in private_key.pem -nocrypt > jwt.der
  4. Set Classpath variable for follwowing 5 jar files jackson-mapper-asl_1.0.0.0_1-1-1.jar,osdt_cert.jar,osdt_core.jar,osdt_restsec.jar,jackson-core-asl_1.0.0.0_1-1-1.jar

    export CLASSPATH=/scratch/aime/work/APPTOP/webtier_mwhome/oracle_common/modules/oracle.osdt_11.1.1/osdt_cert.jar:/scratch/aime/work/APPTOP/webtier_mwhome/oracle_common/modules/oracle.osdt_11.1.1/osdt_core.jar:/scratch/aime/work/APPTOP/webtier_mwhome/oracle_common/modules/oracle.wsm.jersey_11.1.1/jackson-mapper-asl_1.0.0.0_1-1-1.jar:/scratch/aime/work/APPTOP/webtier_mwhome/oracle_common/modules/oracle.wsm.jersey_11.1.1/jackson-core-asl_1.0.0.0_1-1-1.jar:/scratch/aime/work/APPTOP/webtier_mwhome/oracle_common/modules/oracle.osdt_11.1.1/osdt_restsec.jar:/tmp/src

    use sed to change to new destination from /scratch/aime/work/APPTOP to /u01/APPLTOP ; copy above text to src and use sed 's/\/scratch\/aime\/work\/APPTOP/\/u01\/APPLTOP/g' src

  5. Compile and Run

    javac GenerateJWT.java
    java GenerateJWT

section 3Configure Token-based authentication within HCM

  1. Login as security manager user and access the security console.

    Navigator > [Tools] Security Console

  2. Click API Authentication.
  3. Click Create Oracle API Authentication Provider.
  4. On the newly opened Oracle API Authentication Provider Details page, click Edit and enter the following information.

    Attribute Value
    Trusted Issuer [name of the calling provider e.g. PayrollSystem]
    Token Type JWT
  5. Click Save and Close.
  6. Next Select the Inbound API Authentication Public Certificates from the left-hand menu.
  7. Complete the Certificate Alias e.g. 'ORA_ASE_Payroll509'.
  8. Select Browse for the Import Public Certificate, and navigate to the location of the publickey.cer file created in the earlier step.
  9. Select Done which will return you to the API Authentication overview page.

You are now able to configure REST and SOAP services to use JWT to authenticate against your Oracle HCM instance.


next stepNext Tutorial

Authenticate to make JWT Authenticated Calls