Tuesday, 15 February 2022

AIS troubleshooting - you are not authorized [sic]

This is a pretty common problem that I get involved in a little bit.  Troubleshooting "You are not authorized to run this application." in AIS... What application / form / version?

Hey, JDE engineers - can you have some sort of logging option to show the application that cannot be run, please.  I understand that it might be a security risk [perhaps somehow], if you are showing the applications that people cannot run.  It is SO difficult to work out what people cannot run, especially when there are hidden forms and exits or logic controlled popups... 

Good enhancement idea? 

Back to how you can sort this out.  Remember, the situation is AIS if giving you the error about authorized [sic], all you need to do is enable logging for the user in AIS.  I'm sure you know how to do this, here is a screen shot in case:


In server manager under the AIS instance, goto logging and then hit the button for create new user specific log configuration.

Enter the JDE username, cAsE does not matter



Because I love logging, I choose this option and then apply


The thing is, your job is not done, you then need to synchronise the configuration:

You do that by going back out to the AIS server main page and choose synchronize configuration.  This is going to copy the jdelog.properties into the correct location on the AIS server so that you start logging!


You will then have an entry under the logging section of server manager for that user.  You can then work your magic with AIS to replicate the issue and then suss out some sample logs below:

Search your logs for "{"TITLE":"You are not authorized to run this application.","DESC":"INFORMATION"}

Then look up 6 lines for the section in aqua.  This is DEBUG and shows you the application that was attempted to be run!  Awesome, fix your security and go again!  Also nice to see that this is a R FormServiceAction - Read...  U is for update, see here https://docs.oracle.com/cd/E24705_01/doc.91/e56635/config_ais_calls.htm#EOTMD308

You can also see the data being passed into form and the control ID's being requested.  All very handy when dealing with column security too.


  [DEBUG ] BLOXSOMA - [AIS]             JAS INPUT PARAMETERS: FormServiceDemo=false&LoadBaseFormOnly=false&eventCount=0&OID=P17732_W17732D&FormServiceAction=R&Role=*ALL&ReturnControlIDs=1%5B28%2C31%2C33%2C145%5D&MaxPageSize=100&FormDSData=%7C135758%7C&RENDER_MAFLET=AIS&Environment=JPP920&FormDSTmpl=%7C1%7C&FindOnEntry=TRUE&OutputType= 

15 Feb 2022 10:26:21,055 [Line -1] [DEBUG ] BLOXSOMA - [AIS]             JAS URL: http://Server:9007/jde/FormServiceRequest 

15 Feb 2022 10:26:21,056 [Line -1] [DEBUG ] BLOXSOMA - [AIS]             Request Header Cookies JSESSIONID=T0D6xVrOGJgHpraAoZo8k-tK0mDy0kKOJYH-e4myi7_CEmXxWL1Z!1615883497; 

15 Feb 2022 10:26:21,126 [Line -1] [DEBUG ] BLOXSOMA - [AIS]             Response connection headers {null=[HTTP/1.1 503 Service Unavailable], Content-Length=[176], Date=[Tue, 15 Feb 2022 00:26:21 GMT], Content-Type=[application/json; charset=UTF-8]} 

15 Feb 2022 10:26:21,126 [Line -1] [DEBUG ] BLOXSOMA - [AIS]             NOT Gzip Encoding Read with InputStreamReader connection.getContentEncoding()null connection.getContentLength() 176 

15 Feb 2022 10:26:21,126 [Line -1] [DEBUG ] BLOXSOMA - [AIS]             E1ResUtils inputStreamToString END output {"errors":[{"TITLE":"You are not authorized to run this application.","DESC":"INFORMATION"},{"TITLE":"You are not authorized to run this application.","DESC":"INFORMATION"}]} 

Monday, 14 February 2022

Faster load testing in a modern JDE environment

We have a lot of clients going live at the moment.  This is with new databases, new clouds, new hardware, new tools releases.  Everyone gets a little nervous before the go-live, and I think rightfully so.  The projects are getting leaner and therefore the load testing needs to get leaner to match.

I'm going to cover off, what I think is the leanest and meanest JDE specific load testing that can be done:

  • interactive historical comparison
  • batch historical comparison
  • synthetic load test
Interactive historical comparison

Interactive historical allows you to compare the page load times in your current production environment and compare those with your new environment.  You know that we use ERP Insights to provide us with the baseline and also the results from all of the activity that has been done as part of the UAT / testing.


Generally I look at information like the above, put that into excel and compare the load times over the environments.  Very quickly you'll see if you have problem applications, but also tell you overall how things are going.  This information is constantly updated, so you can react quickly after a go-live.


Data like page load time, server response time and page download time are all critical in forming a complete picture of exactly where the performance challenges might be.  You can see from above that all of these are measured - which can include location of browser!

I'd look at the top 20 applications that are slower and see if there are some themes.

Batch historical comparison
fusion5 have spent a lot of time writing detailed statistical analysis tools over the WSJ tables.   We have an agent that sits on premise and uploads your WSJ history to the cloud.  With this information, we can provide immediate feedback on batch performance too.  Once again, for the purposes of an upgrade - we tend to compare the average performance of all batch jobs in production against the new environments.  Ensure that you have run all of the jobs in the scheduler (or have an active scheduler) so that you get a quick view of average runtime of important jobs.

I like to look at those that are slower and faster, to ensure that the testing is solid (top 20 of each).


Very quickly you can see if yours jobs are selecting the correct data, running enough times and also how long they run on average.

Synthetic load test
This is really important to ensure that all of your configuration files, database connections, load balancers etc are configured correctly for production. It's important to look at your historical usage to know what load testing you should actually run.


Simple synthetic load testing will tell you any thresholds that you've not done correctly.  users per JVM and JDBj connections are a classic problem area!

Getting some speedy results from the above [and successful testing] will make you feel pretty confident walking into your next go live.

Summary
An engagement like this takes less than 1 week and can provide you with some really good insights into how JDE is performing and give you confidence going into your new environment.  you should get a solid baseline for JDE performance which you can continue to measure against moving forward.


Thursday, 10 February 2022

Using oauth (JWT) to log into JDE

If I had any recommendations for customers, tidy up your JDE authentication.  Use standards based (not dodgy) products to protect your ERP. Below is how you can use a JWT to log into JDE securely.  You just need a way of generating the JWT in the correct format - which is pretty easy.  You can see that implementing this method of auth will allow you to embrace a standards based approach to auth.  Something like this stands side by side with our myAccess product.

 Using oauth (JWT) to log into JDE

 

1.1      Introduction

Adopting authenticate standards is critical for system adoption and security compliance.  JD Edwards since 9.2.3.2 allows you to log into AIS or HTML using an access_token, which is a JWT.

 This document covers the end to end process (and some helpful websites) to configure JDE to accept JWT’s for interactive logins.

 

1.2      Steps

Commands are run from a linux command line:  

Note that these steps are done on the web server.  You do not necessarily need to do that.  When you are done, all you need is the single key.pfx file (pkcs12 format) which contains the private key for decrypting the contents of the JWT.  You would use the same file on all of your webservers.

 1.2.1      Key generation:

 Generate a private key

$ openssl genrsa -out private.pem 4096

Extract the public key from the private key

$ openssl rsa -in private.pem -out public.pem -pubout

If you try to insert private and public keys to PKCS12 format without a certificate you get an error - Server manager needs pkcs12

openssl pkcs12 -export -inkey private.pem -in public.pem -out keys.p12

unable to load certificates

Generate self-signed certificate with aforesaid key for 10 years. This certificate isn't used for anything as the counterpart is JWK with just public key, no certificate.  This is, open SSL needs the cert (fancy public key)

$ openssl req -key private.pem -new -x509 -days 3650 -subj "/C=AU/ST=Victoria/O=Fusion5/OU=CNC Gurus/CN=fusion5.com.au" -out cert.pem

Convert the above private key and certificate to PKCS12 format - which is what we need for SM

$ chmod 0400 private.pem

$ openssl pkcs12 -export -inkey private.pem -in cert.pem -out keys.pfx -name "fusion5oauth"

Check the keystore:

$ keytool -list -keystore keys.pfx

 

From <https://ruleoftech.com/2020/generating-jwt-and-jwk-for-information-exchange-between-services>

1.2.2      Test key access

 

Ensure jde user can read the cert

sudo su - jde920

Cat /tmp/shannon/keys.pfx

 

/get a pile of binary rubbish/

 

1.3      Configure SM for the instance you want to login with

Goto a webserver (initially) need to see advanced settings and security section.




Generate a JWT: Need to use RS256, as I found out after I had generated a different JWT… Doh!  There are other options.

 

12 Jan 2022 17:10:18,550[WARN][JAVATOKEN]OAuthJWTAuthenticationManager: getJWTPayload() - JWT token validation failed com.nimbusds.jose.JOSEException: Unsupported JWS algorithm HS256, must be RS256, RS384, RS512, PS256,

 

 

1.3.1      Generate a test JWT

 

This is an awesome site for creating a JWT for testing: 

https://jwt.io/#debugger

 

This will load up an example with the correct HEADER.BODY.CERT JWT 

 https://jwt.io/#debugger-io?token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIxMjM0NTY3ODkwIiwicHJuIjoiU00wMDAwMSIsImFkbWluIjp0cnVlLCJpYXQiOjE2NMTg5MDEsImV4cCI6MTY0MjExODkwMSwiaXNzIjoic2hhbm5vbiIsImF0X3VzZV9uYnIiOjF9.dBhGniUgkDpmuISE05GmsWrmvj0Ip33Ssx6Ud600FsWnWx9ir3mPG_JnVGzTMh4F9SevQ4des35DRryUm21ONzKWPY9KxufK6uVX1UQ1OVLeSIPhHaXZbru7rkxNUvpxm4Q72jhX6UN0_DvjqbQAh7R80jO3WQwBYpAuIXAksR9rHtucDK8Kfb0tFgOP16FK4VpnnqhGx4FxpUFDhUS3LH_0ApbF6xflcevHMys7VMjZX9lpOjqjUH6-nVHfd2wtUpZopz0kY0yFBcnZ_Py150PUrmgZuZyg-ff3rB4-g9sxs7FvULH11DKBZtj8aj3bGrlak9GWc7L7bkTNmC22wP9_KZNGS2FquNG3IZA3qcS7spd80Ix6TEnOYRZgWT2mqdGbj_mQXwlVSaA_lkobXMByO8vaCiGTXB2NSwSDU3VuEXT2vun4FkQSw-Qa5sPnhFpCQUk6CQ8JI0-rFqSQSeB8X_ORn6IX7G-YglN2sbL0_z4zQSV-CENILsngeEP53nTT8Z_m8Rw80Eg5_dNLFSLj1nTCfePKox7ZNhaWWChZkyiiPQty4IfZc-3QgJo6l7AAHMkONAMdo1vH9iwfkkw7P8ztT7ZLkaRvO5Ut9Q4EnI4SwtnJd9Ksq0PM9A08ZOoLolPKfw-QYUEfTaMKk_n6MxQEyRDz06yKkTi4o&publicKey=-----BEGIN%20PUBLIC%20KEY-----%0AMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAqsbe4zhXWdUSppclxsfJ%0AygSoXhAOgEi4OeQAYbuz1JzS2KoBp0QO6CLNKn0nEh8JWPwUkwz4cbtazQnBWjL8%0AmXunzecgyyhWh%2F0nYeLAhrEkVuLcCpAqGagEcHSn0myJsfRAN4D394SQ09gSCAvn%0ACsg1E0ZHSGVRpguAAU8z%2Brkxc%2BjczGide%2Bp1HfoT8EcZxtKZ5qzBnPi1OTPuld9Q%0AJZPm7sMpo03D4BHFuXSb8FJaiOJMdVK%2F8eMUuqbghuK7%2yHvfK6YPF%2Baw9%0A85%2B5aeKmNElriJoCu4uPSFF4XeeujrJOkbYCJ3S8ZBKb8xGO1G64F4Po%2Bf%2F%2Frr6s%0Ab4w0T%2BCbAUwek7UUJ2pI%2BfOtRbD6uwJxDQ%2FZVaAaa4njbJouMLAYD3idm9lo7K%2B0%0AK%2FShM6P9be1RUwoyIB3eVtNiC5Al5%2Bd0FaQaMRyKH%2F%2Bgj9lHqodWEbsm%2BucelZjt%0ADVSbtDat5QpZ2mAJVyI%2BfyDuUGwAXxfi12ZsCpuX0VH5V6O0EpgDxTSTeUQfb1RR%0Aqx1wIuFSxhgQVf6oJ1DcgjyEPtvA9RM7usfez5K1bvUzlhBqeMKVKvNMaNv9eP99%0AVfHXOxH65nj8iKdA%2BT5DFSvEqa2wbXROI9gpXiO9X4AlGx3I9FWSFK2XCEqmAxwx%0A0kkAFjCIolEabw1GBqtOeU0CAwEAAQ%3D%3D%0A-----END%20PUBLIC%20KEY-----

 

Note that the private key is not copied…



 

A couple of things to note:

 

Firstly, remember to paste the entire contents of the private and public keys, with header.

 

{

  "jti": "1234567890",  something unique

  "prn": "SM00001",  your jde username

  "admin": true,

  "iat": 1642118901,   You might need this - https://www.epochconverter.com/

  "exp": 1642118901,

  "iss": "shannon", 

  "at_use_nbr": 1  single use

}

 

Note that you need the private key to generate the JWT.  The private key encrypts the contents so that they cannot be tampered with in transit.

 

This is all about trust.  We are trusting the person with the private key is being VERY good, a good citizen.  Because if you get a hold of the certificate - then you can generate tokens and login as ANYONE!!!  The private key is to be treated like a password.

 

1.3.2      Now, login to JDE:

 

https://f5play.fusion5.cloud/jde/E1Menu.maf?access_token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIxMjM0NTY1Nzg5MCIsInBybiI6IlNNMDAwMDEiLCJhZG1pbiI6dHJ1ZSwiaWF0IjoxNjQyMTE4OTAxLCJleHAiOjE2NDIxMTg5MDEsImlzcyI6InNoYW5ub24iLCJhdFfbmJyIjoxfQ.JjBO6K7-WLCHefpOT3Kw2t2SZTspwcEw7eF334mhk0AIDi3Sw53FPWFXsrGvYengKFnzS9wm8cA1JsWjgsqKFv_OKlqx3hh1613-_1MpLryjaOWVlQpo5X7ZGJ1ae5N-mjPZwqHjCAz2JE1yZWnLUn-BTHa3-DkcANp0DyWe1T1hbFjwgUY_BIKZdOTBCUwNSRUFhir0bGl2ifUj55vQkAQMFskkrGXe371UenfsPyzZfabKNF4_WhTXa2hHeebsmGebmaGW_i-YVR6v0LZYIG8VcksZ9uQj1F55gyRIDS49jtzwzFdxY_gjjLMlTjl3o7zEbMAyv80rHh1Sjv2UJDXkhdXmDolpJvKcTbG3AEeLzMVE4ua_69fNoToa4t_5MktdRw4XqQwzd46JiBPPsGUCg_AaOi4nWmclx8B1HqvApyIQm3TdE7_wJqRt2zLqYRxySbNi0ewFk3vqxa3j3JlhqJiHQxQ7YJRXW4BaUNRMT8FBlp8yKgrQSE0u_uJ7MThq6PeIYqW7gLeNj78Hdu-I1dAnESGQ0KsAB_AckVQLwAEiUDcaZqkZIFBTTAp2smqKFeQ1oG579bcKEnzsNstqzlzpPw46T_VE21oN3VQYcnc8rfgVwk7KDbtd-SflX86fOrt2h4tAs9gFRI3rjjCM0gyjzqrNvzc

 

Okay!

 

This is good reference:

Every Private Key has a corresponding Public Key. The public key is mathematically derived from the private key. These two keys, together called a "key pair", can be used for two purposes: Encryption and Signing. For the purposes of certificates, signing is far more relevant.

A certificate is basically just a public key, which has been signed by someone else's private key. This forms the basis of public key infrastructure (PKI), which is explained in the articles linked in the question.

How do Certificates and Private Keys relate? https://security.stackexchange.com/questions/226747/what-is-the-difference-between-a-certificate-and-a-private-key 

A certificate is just a "fancy" public key, which is related to a private key. You can do the same thing with a certificate as you can do with a public key.

If Bob gets the certificate of Alice, he can encrypt a message for Alice. Likewise, if Alice publishes some data and signs it with her private key, Bob can use Alice's certificate to see if it is really from Alice.

What are all those different file types?

  • .pem: A .pem is a de-facto file format called Privacy-Enhanced Mail. A PEM file can contain a lot of different things, such as certificates, private keys, public keys and lots of other things. A file being in PEM format says nothing about the content, just like something being Base64-encoded says nothing about the content.
  • .crt.cer: This is another pseudo-format that is commonly used to store certificates. These can either be in the PEM or in the DER format.
  • .p12.pfx: These are interchangable file extensions for the PKCS#12 format. Technically, PKCS#12 is the successor to Microsoft's PFX format, but they have become interchangable. PKCS#12 files are archives for cryptographic material. Again, what kind of material this contains is completely up to the user.

Wait, what!?

Yes, .crt.pem.pfx and .p12 can all be used to store certificates, public keys and private keys. From a purely technical standpoint, you can not tell what the semantic content of any of these files is just by their file extension. If you ever get confused, don't worry - you're not alone.

However, there are some common conventions that are being followed. .p12 and .pfx files are usually used to store a certificate together with the private key that corresponds to this certificate.

Likewise, .crt files usually contain single certificates without any related private key material.

.pem files are wildcards. They can contain anything, and it's not uncommon to see them used for all different kinds of purposes. Luckily, they are all plain text, and are prefixed in a human-readable way, such as

-----BEGIN CERTIFICATE-----
MIICLDCCAdKgAwIBAgIBADAKBggqhkjOPQQDAjB9MQswCQYDVQQGEwJCRTEPMA0G
A1UEChMGR251VExTMSUwIwYDVQQLExxHbnVUTFMgY2VydGlmaWNhdGUgYXV0aG9y
...

Why would an application not handle a .crt file if it wants a client certificate?

A certificate is just a public key, and thus by definition public. A client certificate is no different - just a public key by a person, machine or other "client", that is signed by some authority.

An application that wants a client certificate usually wants to use that certificate for something, such as to authenticate the client to a server. In order to do that, one needs the certificate and the corresponding private key.

So an application should really write "certificate plus private key", because the certificate alone is not enough to prove one's identity. It's actually the private key that does it.

 

To answer vitm's question: As the answer explains, a private key is always associated with a public key, and a certificate contains a public key, as well as other information regarding the individual holding the public key.

If a server program or client program want to use a certificate (e.g. a web server using a server certificate or a web browser using a client certificate), they need both the certificate and the private key.

However, that private key is never sent anywhere. The private key is used mathematically to decrypt messages, which are encrypted with the public key in the certificate - and to sign messages, which are verified using the public key in the certificate.

If I only had a certificate, without a public key, then I would not be able to act as the server or client, to whom the certificate relates to, as I could not sign messages or decrypt messages.

Extending JDE to generative AI