Before 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.
Generate 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:
generate a private key (private.key).
openssl genrsa -out private.key 2048
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
Generate 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:
- 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)
Header | The header consists of three parts: |
---|---|
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
- Create a directory /tmp/src
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); } }
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
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
Compile and Run
javac GenerateJWT.java java GenerateJWT
Configure Token-based authentication within HCM
Login as security manager user and access the security console.
Navigator > [Tools] Security Console
- Click API Authentication.
- Click Create Oracle API Authentication Provider.
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 - Click Save and Close.
- Next Select the Inbound API Authentication Public Certificates from the left-hand menu.
- Complete the Certificate Alias e.g. 'ORA_ASE_Payroll509'.
- Select Browse for the Import Public Certificate, and navigate to the location of the publickey.cer file created in the earlier step.
- 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.