Setup JWT Keys
Log onto server
Switch to edxapp user
sudo -H -u edxapp bash
source /edx/app/edxapp/edxapp_env
cd /edx/app/edxapp/edx-platform
Create a new file which you can call key_gen.py, with the following code:
from Cryptodome.PublicKey import RSA
from jwkest import jwk
# Ask for Key Identifier
key_identifier = raw_input("Key Identifier? ")
print ""
print ""
rsa_key = RSA.generate(2048)
rsa_jwk = jwk.RSAKey(kid=key_identifier, key=rsa_key)
public_keys = jwk.KEYS()
public_keys.append(rsa_jwk)
serialized_public_keys_json = public_keys.dump_jwks()
print "JWT_PUBLIC_SIGNING_JWK_SET value for ecommerce.yml and discovery.yml is"
print ""
print (serialized_public_keys_json)
print ""
print ("JWT_PUBLIC_SIGNING_JWK_SET value for lms.env.json and cms.env.json is")
JWT_PUBLIC_SIGNING_JWK_SET = serialized_public_keys_json.replace('"', '\\"')
print ""
print (JWT_PUBLIC_SIGNING_JWK_SET)
print ""
print ""
print ("JWT_PRIVATE_SIGNING_JWK value for lms.env.json and cms.env.json is")
# Converting to string
JWT_PRIVATE_SIGNING_JWK = str(rsa_jwk)
#print JWT_PRIVATE_SIGNING_JWK
# Replacing single quotes by double quotes
JWT_PRIVATE_SIGNING_JWK = JWT_PRIVATE_SIGNING_JWK.replace('\'', '\"')
#print JWT_PRIVATE_SIGNING_JWK
# Escaping double quotes
JWT_PRIVATE_SIGNING_JWK = JWT_PRIVATE_SIGNING_JWK.replace('"', '\\"')
#print JWT_PRIVATE_SIGNING_JWK
# removing unicode for some values
JWT_PRIVATE_SIGNING_JWK = JWT_PRIVATE_SIGNING_JWK.replace('u\\', '\\')
print ""
print (JWT_PRIVATE_SIGNING_JWK)
print ""
print ""
Note: If you run into error like SyntaxError: Non-ASCII character '\xe2' in file while copying the code, please remove the blank line spaces between the code.
Run the file
python2 key_gen.py
When prompted, enter an Key ID (I think this can be anything).
ecommerce_key
YAML for JWT_PUBLIC_SIGNING_JWK_SET and JSON Arrays should be returned for JWT_PUBLIC_SIGNING_JWK_SET and JWT_PRIVATE_SIGNING_JWK. Save these.
JWT_PUBLIC_SIGNING_JWK_SET value for ecommerce.yml and discovery.yml is
{"keys": [{"kid": "ecommerce_key", "e": "AQAB", "kty": "RSA", "n": "nRAd4fvJJAn8atyavxEisT28t0yGP44AV-G-aM10GmYSP-JTZUWSMCzftaEaHewvpvzoKDQK8IZM44PXEyqr_K4lgEXdDN_4TPJ8qDv6ibgQUxLKAcxm8SfWK7rQ3IivTZeaF1zBs-efqrMJbo6piDgcRkowEyYRtDrM-2rgA4Hb4Fu8cpt0tP_sbuc1JdZVMSUCxjNfAk0YuZU9w08r0xnQf4vITMihIoX_VyBjcJve4C5S4T7jz_hwc55NYqc2pZUj9jzZlrt06vcLztcld7q5F7vvhlx09WZWjhFrwVVreYLuUORQnZ6ZF8uTmEfpCubKwstebe4CwyPipyC1eQ"}]}
JWT_PUBLIC_SIGNING_JWK_SET value for lms.env.json and cms.env.json is
{\"keys\": [{\"kid\": \"ecommerce_key\", \"e\": \"AQAB\", \"kty\": \"RSA\", \"n\": \"nRAd4fvJJAn8atyavxEisT28t0yGP44AV-G-aM10GmYSP-JTZUWSMCzftaEaHewvpvzoKDQK8IZM44PXEyqr_K4lgEXdDN_4TPJ8qDv6ibgQUxLKAcxm8SfWK7rQ3IivTZeaF1zBs-efqrMJbo6piDgcRkowEyYRtDrM-2rgA4Hb4Fu8cpt0tP_sbuc1JdZVMSUCxjNfAk0YuZU9w08r0xnQf4vITMihIoX_VyBjcJve4C5S4T7jz_hwc55NYqc2pZUj9jzZlrt06vcLztcld7q5F7vvhlx09WZWjhFrwVVreYLuUORQnZ6ZF8uTmEfpCubKwstebe4CwyPipyC1eQ\"}]}
JWT_PRIVATE_SIGNING_JWK value for lms.env.json and cms.env.json is
{\"e\": \"AQAB\", \"d\": \"DTckRzXSrdKdR4yPr2X3X6ch2uEjJp6BzuMyt0oaQSJiL2KRa82tHZqY_tpdrTOIqun6ysSI6xtnGs78E3kdXDchoVJqOsFu-LfVNKlJ97k3aRYFTfNvR06idFmAEMj7dHGTc0XIZ_p5nSOlYS-7JLgRQPoluLwU9JpB_Hb4qbLAnH6-Ptxh-Blrvj2DnGSw18nb2vdDItqduXe0D5paEF4VddfAKORC0PmldNR4xWrUFce2Jqn_P9bHC1v4Fe6GedcpI5P6OLT3ehZ01u6YXfOKcGaKqEgqAyc4TrROPM4Ta_ui6PI3sFo7DLxmylSAGWyX8KVSlkCQ4jy0mCrLBQ\", \"n\": \"nRAd4fvJJAn8atyavxEisT28t0yGP44AV-G-aM10GmYSP-JTZUWSMCzftaEaHewvpvzoKDQK8IZM44PXEyqr_K4lgEXdDN_4TPJ8qDv6ibgQUxLKAcxm8SfWK7rQ3IivTZeaF1zBs-efqrMJbo6piDgcRkowEyYRtDrM-2rgA4Hb4Fu8cpt0tP_sbuc1JdZVMSUCxjNfAk0YuZU9w08r0xnQf4vITMihIoX_VyBjcJve4C5S4T7jz_hwc55NYqc2pZUj9jzZlrt06vcLztcld7q5F7vvhlx09WZWjhFrwVVreYLuUORQnZ6ZF8uTmEfpCubKwstebe4CwyPipyC1eQ\", \"q\": \"3J4oXQRqKl-0ITFGdZBVAzsoLIW9PT492KnsG-s4q2p30YeZaiIySHre0Zw_n4cZNHJoe1DClYhrjl5ceiS4y9mdYJqbEzWFkkXEBDnNN6PjjlVPCo3AFWnTnwmh869w8nlIeUc2ylXiVKL_qIlvDzg_RrGKY-dTjPnR-AgDk3c\", \"p\": \"tkCbFOQgwXOT4gkQQFqzyb6l5oItdRemjTrwekDFebSnW7Zqo1cG5I1DMPUk335Rxd5MuUsutByHcQCNGuElmNE_ApmmTYk4Op39vNoJS8_KVfPSaBT__Im8fjO8mSZhzuYen3lCx9n94KE0Lbhz_zqg5CeqJnKWWlvS4EJi2o8\", \"kid\": \"ecommerce_key\", \"kty\": \"RSA\"}
In lms.env.json, modify JWT_PUBLIC_SIGNING_JWK_SET, JWT_PRIVATE_SIGNING_JWK, and JWT_SIGNING_ALGORITHM
The following is an excerpt with some values changed.
"JWT_AUTH": {
"JWT_AUDIENCE": "ecommerce-key",
"JWT_ISSUER": "https://example.com/oauth2",
"JWT_ISSUERS": [
{
"AUDIENCE": "ecommerce-key",
"ISSUER": "https://example.com/oauth2",
"SECRET_KEY": "ecommerce-secret"
}
],
"JWT_PRIVATE_SIGNING_JWK": "{\"e\": \"AQAB\", \"d\": \"DTckRzXSrdKdR4yPr2X3X6ch2uEjJp6BzuMyt0oaQSJiL2KRa82tHZqY_tpdrTOIqun6ysSI6xtnGs78E3kdXDchoVJqOsFu-LfVNKlJ97k3aRYFTfNvR06idFmAEMj7dHGTc0XIZ_p5nSOlYS-7JLgRQPoluLwU9JpB_Hb4qbLAnH6-Ptxh-Blrvj2DnGSw18nb2vdDItqduXe0D5paEF4VddfAKORC0PmldNR4xWrUFce2Jqn_P9bHC1v4Fe6GedcpI5P6OLT3ehZ01u6YXfOKcGaKqEgqAyc4TrROPM4Ta_ui6PI3sFo7DLxmylSAGWyX8KVSlkCQ4jy0mCrLBQ\", \"n\": \"nRAd4fvJJAn8atyavxEisT28t0yGP44AV-G-aM10GmYSP-JTZUWSMCzftaEaHewvpvzoKDQK8IZM44PXEyqr_K4lgEXdDN_4TPJ8qDv6ibgQUxLKAcxm8SfWK7rQ3IivTZeaF1zBs-efqrMJbo6piDgcRkowEyYRtDrM-2rgA4Hb4Fu8cpt0tP_sbuc1JdZVMSUCxjNfAk0YuZU9w08r0xnQf4vITMihIoX_VyBjcJve4C5S4T7jz_hwc55NYqc2pZUj9jzZlrt06vcLztcld7q5F7vvhlx09WZWjhFrwVVreYLuUORQnZ6ZF8uTmEfpCubKwstebe4CwyPipyC1eQ\", \"q\": \"3J4oXQRqKl-0ITFGdZBVAzsoLIW9PT492KnsG-s4q2p30YeZaiIySHre0Zw_n4cZNHJoe1DClYhrjl5ceiS4y9mdYJqbEzWFkkXEBDnNN6PjjlVPCo3AFWnTnwmh869w8nlIeUc2ylXiVKL_qIlvDzg_RrGKY-dTjPnR-AgDk3c\", \"p\": \"tkCbFOQgwXOT4gkQQFqzyb6l5oItdRemjTrwekDFebSnW7Zqo1cG5I1DMPUk335Rxd5MuUsutByHcQCNGuElmNE_ApmmTYk4Op39vNoJS8_KVfPSaBT__Im8fjO8mSZhzuYen3lCx9n94KE0Lbhz_zqg5CeqJnKWWlvS4EJi2o8\", \"kid\": \"ecommerce_key\", \"kty\": \"RSA\"}",
"JWT_PUBLIC_SIGNING_JWK_SET": "{\"keys\": [{\"kid\": \"ecommerce_key\", \"e\": \"AQAB\", \"kty\": \"RSA\", \"n\": \"nRAd4fvJJAn8atyavxEisT28t0yGP44AV-G-aM10GmYSP-JTZUWSMCzftaEaHewvpvzoKDQK8IZM44PXEyqr_K4lgEXdDN_4TPJ8qDv6ibgQUxLKAcxm8SfWK7rQ3IivTZeaF1zBs-efqrMJbo6piDgcRkowEyYRtDrM-2rgA4Hb4Fu8cpt0tP_sbuc1JdZVMSUCxjNfAk0YuZU9w08r0xnQf4vITMihIoX_VyBjcJve4C5S4T7jz_hwc55NYqc2pZUj9jzZlrt06vcLztcld7q5F7vvhlx09WZWjhFrwVVreYLuUORQnZ6ZF8uTmEfpCubKwstebe4CwyPipyC1eQ\"}]}",
"JWT_SECRET_KEY": "ecommerce-secret",
"JWT_SIGNING_ALGORITHM": "RS512"
},
"JWT_EXPIRATION": 30,
"JWT_ISSUER": "https://example.com/oauth2",
"JWT_PRIVATE_SIGNING_KEY": "{\"e\": \"AQAB\", \"d\": \"DTckRzXSrdKdR4yPr2X3X6ch2uEjJp6BzuMyt0oaQSJiL2KRa82tHZqY_tpdrTOIqun6ysSI6xtnGs78E3kdXDchoVJqOsFu-LfVNKlJ97k3aRYFTfNvR06idFmAEMj7dHGTc0XIZ_p5nSOlYS-7JLgRQPoluLwU9JpB_Hb4qbLAnH6-Ptxh-Blrvj2DnGSw18nb2vdDItqduXe0D5paEF4VddfAKORC0PmldNR4xWrUFce2Jqn_P9bHC1v4Fe6GedcpI5P6OLT3ehZ01u6YXfOKcGaKqEgqAyc4TrROPM4Ta_ui6PI3sFo7DLxmylSAGWyX8KVSlkCQ4jy0mCrLBQ\", \"n\": \"nRAd4fvJJAn8atyavxEisT28t0yGP44AV-G-aM10GmYSP-JTZUWSMCzftaEaHewvpvzoKDQK8IZM44PXEyqr_K4lgEXdDN_4TPJ8qDv6ibgQUxLKAcxm8SfWK7rQ3IivTZeaF1zBs-efqrMJbo6piDgcRkowEyYRtDrM-2rgA4Hb4Fu8cpt0tP_sbuc1JdZVMSUCxjNfAk0YuZU9w08r0xnQf4vITMihIoX_VyBjcJve4C5S4T7jz_hwc55NYqc2pZUj9jzZlrt06vcLztcld7q5F7vvhlx09WZWjhFrwVVreYLuUORQnZ6ZF8uTmEfpCubKwstebe4CwyPipyC1eQ\", \"q\": \"3J4oXQRqKl-0ITFGdZBVAzsoLIW9PT492KnsG-s4q2p30YeZaiIySHre0Zw_n4cZNHJoe1DClYhrjl5ceiS4y9mdYJqbEzWFkkXEBDnNN6PjjlVPCo3AFWnTnwmh869w8nlIeUc2ylXiVKL_qIlvDzg_RrGKY-dTjPnR-AgDk3c\", \"p\": \"tkCbFOQgwXOT4gkQQFqzyb6l5oItdRemjTrwekDFebSnW7Zqo1cG5I1DMPUk335Rxd5MuUsutByHcQCNGuElmNE_ApmmTYk4Op39vNoJS8_KVfPSaBT__Im8fjO8mSZhzuYen3lCx9n94KE0Lbhz_zqg5CeqJnKWWlvS4EJi2o8\", \"kid\": \"ecommerce_key\", \"kty\": \"RSA\"}",
Next edit /edx/etc/ecommerce.yml and update JWT_ALGORITHM JWT_PUBLIC_SIGNING_JWK_SET
JWT_AUTH:
JWT_ALGORITHM: RS512
JWT_DECODE_HANDLER: ecommerce.extensions.api.handlers.jwt_decode_handler
JWT_ISSUERS:
- AUDIENCE: ecommerce-key
ISSUER: https://example.com/oauth2
SECRET_KEY: ecommerce-secret
- AUDIENCE: ecommerce-key
ISSUER: https://example.com/oauth2
SECRET_KEY: ecommerce-secret
JWT_LEEWAY: 1
JWT_PUBLIC_SIGNING_JWK_SET: '{"keys": [{"kid": "ecommerce_key", "e": "AQAB", "kty": "RSA", "n": "nRAd4fvJJAn8atyavxEisT28t0yGP44AV-G-aM10GmYSP-JTZUWSMCzftaEaHewvpvzoKDQK8IZM44PXEyqr_K4lgEXdDN_4TPJ8qDv6ibgQUxLKAcxm8SfWK7rQ3IivTZeaF1zBs-efqrMJbo6piDgcRkowEyYRtDrM-2rgA4Hb4Fu8cpt0tP_sbuc1JdZVMSUCxjNfAk0YuZU9w08r0xnQf4vITMihIoX_VyBjcJve4C5S4T7jz_hwc55NYqc2pZUj9jzZlrt06vcLztcld7q5F7vvhlx09WZWjhFrwVVreYLuUORQnZ6ZF8uTmEfpCubKwstebe4CwyPipyC1eQ"}]}'
JWT_SECRET_KEY: ecommerce-secret
JWT_VERIFY_EXPIRATION: true
Now edit /edx/etc/discovery.yml and update JWT_ALGORITHM JWT_PUBLIC_SIGNING_JWK_SET
JWT_AUTH:
JWT_ISSUERS:
- AUDIENCE: SET-ME-PLEASE
ISSUER: https://example.com/oauth2
SECRET_KEY: SET-ME-PLEASE
JWT_PUBLIC_SIGNING_JWK_SET: '{"keys": [{"kid": "ecommerce_key", "e": "AQAB", "kty": "RSA", "n": "nRAd4fvJJAn8atyavxEisT28t0yGP44AV-G-aM10GmYSP-JTZUWSMCzftaEaHewvpvzoKDQK8IZM44PXEyqr_K4lgEXdDN_4TPJ8qDv6ibgQUxLKAcxm8SfWK7rQ3IivTZeaF1zBs-efqrMJbo6piDgcRkowEyYRtDrM-2rgA4Hb4Fu8cpt0tP_sbuc1JdZVMSUCxjNfAk0YuZU9w08r0xnQf4vITMihIoX_VyBjcJve4C5S4T7jz_hwc55NYqc2pZUj9jzZlrt06vcLztcld7q5F7vvhlx09WZWjhFrwVVreYLuUORQnZ6ZF8uTmEfpCubKwstebe4CwyPipyC1eQ"}]}'
Restart Everything
sudo /edx/bin/supervisorctl restart all
Note: There is a chance that changes may not take place and you'll see errors like [{"detail":"Incorrect authentication credentials."}]. Issue sudo reboot and test.