Skip to content

Commit

Permalink
fix(auth): token creation and validation (#175)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kif-Fando authored Feb 28, 2022
1 parent 5142d63 commit 55e99c9
Show file tree
Hide file tree
Showing 16 changed files with 207 additions and 37 deletions.
7 changes: 6 additions & 1 deletion .env
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ AWS_BUCKET=https://neuralegion-open-bucket.s3.amazonaws.com
GOOGLE_MAPS_API=AIzaSyD2wIxpYCuNI0Zjt8kChs2hLTS5abVQfRQ
JWT_PRIVATE_KEY_LOCATION=config/keys/jwtRS256.key
JWT_PUBLIC_KEY_LOCATION=config/keys/jwtRS256.key.pub.pem
JWT_SECRET_KEY=123
JWT_SECRET_KEY=1234
JWK_PRIVATE_KEY_LOCATION=config/keys/jwk.key.pem
JWK_PUBLIC_KEY_LOCATION=config/keys/jwk.pub.key.pem
JWK_PUBLIC_JSON=config/keys/jwk.pub.json
JKU_URL=https://raw.githubusercontent.com/NeuraLegion/brokencrystals/development/config/keys/jku.json
X5U_URL=https://raw.githubusercontent.com/NeuraLegion/brokencrystals/development/config/keys/x509.crt

KEYCLOAK_SERVER_URI=https://auth.qa.brokencrystals.com/auth
KEYCLOAK_REALM=brokencrystals
Expand Down
14 changes: 14 additions & 0 deletions config/keys/jku.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"p": "431uI38cmvm6iSyRvJBd6AUCYH3gGwa00Xhjw7y4rjRtZVvIGkh6WhVklOSCbLej5MTCdlCW1t4kftsYObWT21ZYxrXyx1tVinI5qkRG3rN2yj8lM5FY8j9fqRuseCpK9Igx9vcCj1ntwWJqWYiu1WFf0WJVfOmt6bulmTKJWYk",
"kty": "RSA",
"q": "4amVVFOXmHw296-zjPIj0Vs7axjyYmW0T6iK00Hz5qCPAa8Y1FofsZHYu6AUY5hC8FCCzecgI4v9v1dY7Bo_8Gh6B4yweI88eZQ80tnJVyB69Ar3ZxuKfuQSjkGBFwjaUxidwaJ2-Kzif4BthoXGwdc__JUkSkh_SE-iDp6YhVE",
"d": "rJUqAKV1x9IDscFiwCc3d1nZWhr1z0X42CRQYy10Ysq-BIKtvvB6xDEK8aHbNGK67TCMeHp6JWaOwun4eNkz67-1qmlnR9wRwhxPHQtpe9nmDYty3hTrMbayogsjWTq6hkOvZrYA8q50dJ4pTXLii2EMy8PHKNxJBy_BnTdsq1RwKrN9NhyHn6weNjKXNgOsUfYh99T2D6Mc14SseAtwkntj26VQAcJoJXOIDAl972uEfE7nOO-mQCPQqkBzvzX1l8-09Q2LZlC30MfEjC9LnI2-XWAqGlzM3TtKkHbRj3tXV9ZrvmWFBcQk6I1fPZ20pFve1iUzuYVIhEHqvJavgQ",
"e": "AQAB",
"use": "sig",
"kid": "sig-1645503536",
"qi": "RWi4iZKKsBpIjbdSam61WHORl3WZEYyvLP-wWs3OcnfUVfhqBV5aCMz2IwCmwVr0-y8iyNLDEuExesTSmxaDWwQVjpBi_idgwPpLF5xUaBBlp4ARJx9PxPrEVHhk_S2TwHHBwofWdxd2gRlBMKUZZ9jOaa2IomIrXrysGpll9m8",
"dp": "zG1x5QocHZQesZhQmn-tM4wU17smAYNkR_yEwme8GifYysXQqvXIpV0mFrrGDYZ1DGZYTdQbyJi1eR3PxkRKy0br3h2xPr7vvsro0P4sJYJmVFasSovpvz996kyJDy8KTnZ5V_Ie5c0tX6Pd5_lxCyVG4rUYF3kypKDQrjuAu-k",
"alg": "RS256",
"dq": "1NGpSnj3fFCRSnCCxgdKrlP7KprBZPkD3yhVnL0Td8quc-kdYo-IWl_w5aon8HGVl6xmYCd8UOniqkSHUUvER0dQ5rPRbjGv1_1si3Hnh2rTajq5bp0ztU4FDfJK-11XAY0yon5E82ugxJxrLrYVZ5RH_T7ulbvfhmPLszvxHbE",
"n": "yIfwTdiyO-t7iiRpithhH4JxWdZTHWx_7h9dgoeWz4kf07RuQ1aRCOZPqt_iCUI_zjwOLwtIG1g_eg4mKmij49ukTvO_nBb5NyH4GYBMuE6xU7lu4mt-KryNDM_YcRjpg9IArGzNPv_5MAlby3XJFQa5A0sPz7khlskwX8En3g_dgOXPtbyAT-Alhz2StrhdAYBR09h54Hs2yl3P7YWQfO8IaM38XFfxSEvQSD-pA9x7yWAGYFA9Uc-RhkhYHQobGaLuBFdDgqa9hbbeOojG8M2rOQHtcS9hjW-lelUKzivXkR2DfZb56iSSu3dZLYy1MzUQEJfpDvgpAVsIEFGBWQ"
}
18 changes: 18 additions & 0 deletions config/keys/jwk.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"keys": [
{
"p": "431uI38cmvm6iSyRvJBd6AUCYH3gGwa00Xhjw7y4rjRtZVvIGkh6WhVklOSCbLej5MTCdlCW1t4kftsYObWT21ZYxrXyx1tVinI5qkRG3rN2yj8lM5FY8j9fqRuseCpK9Igx9vcCj1ntwWJqWYiu1WFf0WJVfOmt6bulmTKJWYk",
"kty": "RSA",
"q": "4amVVFOXmHw296-zjPIj0Vs7axjyYmW0T6iK00Hz5qCPAa8Y1FofsZHYu6AUY5hC8FCCzecgI4v9v1dY7Bo_8Gh6B4yweI88eZQ80tnJVyB69Ar3ZxuKfuQSjkGBFwjaUxidwaJ2-Kzif4BthoXGwdc__JUkSkh_SE-iDp6YhVE",
"d": "rJUqAKV1x9IDscFiwCc3d1nZWhr1z0X42CRQYy10Ysq-BIKtvvB6xDEK8aHbNGK67TCMeHp6JWaOwun4eNkz67-1qmlnR9wRwhxPHQtpe9nmDYty3hTrMbayogsjWTq6hkOvZrYA8q50dJ4pTXLii2EMy8PHKNxJBy_BnTdsq1RwKrN9NhyHn6weNjKXNgOsUfYh99T2D6Mc14SseAtwkntj26VQAcJoJXOIDAl972uEfE7nOO-mQCPQqkBzvzX1l8-09Q2LZlC30MfEjC9LnI2-XWAqGlzM3TtKkHbRj3tXV9ZrvmWFBcQk6I1fPZ20pFve1iUzuYVIhEHqvJavgQ",
"e": "AQAB",
"use": "sig",
"kid": "sig-1645503536",
"qi": "RWi4iZKKsBpIjbdSam61WHORl3WZEYyvLP-wWs3OcnfUVfhqBV5aCMz2IwCmwVr0-y8iyNLDEuExesTSmxaDWwQVjpBi_idgwPpLF5xUaBBlp4ARJx9PxPrEVHhk_S2TwHHBwofWdxd2gRlBMKUZZ9jOaa2IomIrXrysGpll9m8",
"dp": "zG1x5QocHZQesZhQmn-tM4wU17smAYNkR_yEwme8GifYysXQqvXIpV0mFrrGDYZ1DGZYTdQbyJi1eR3PxkRKy0br3h2xPr7vvsro0P4sJYJmVFasSovpvz996kyJDy8KTnZ5V_Ie5c0tX6Pd5_lxCyVG4rUYF3kypKDQrjuAu-k",
"alg": "RS256",
"dq": "1NGpSnj3fFCRSnCCxgdKrlP7KprBZPkD3yhVnL0Td8quc-kdYo-IWl_w5aon8HGVl6xmYCd8UOniqkSHUUvER0dQ5rPRbjGv1_1si3Hnh2rTajq5bp0ztU4FDfJK-11XAY0yon5E82ugxJxrLrYVZ5RH_T7ulbvfhmPLszvxHbE",
"n": "yIfwTdiyO-t7iiRpithhH4JxWdZTHWx_7h9dgoeWz4kf07RuQ1aRCOZPqt_iCUI_zjwOLwtIG1g_eg4mKmij49ukTvO_nBb5NyH4GYBMuE6xU7lu4mt-KryNDM_YcRjpg9IArGzNPv_5MAlby3XJFQa5A0sPz7khlskwX8En3g_dgOXPtbyAT-Alhz2StrhdAYBR09h54Hs2yl3P7YWQfO8IaM38XFfxSEvQSD-pA9x7yWAGYFA9Uc-RhkhYHQobGaLuBFdDgqa9hbbeOojG8M2rOQHtcS9hjW-lelUKzivXkR2DfZb56iSSu3dZLYy1MzUQEJfpDvgpAVsIEFGBWQ"
}
]
}
28 changes: 28 additions & 0 deletions config/keys/jwk.key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDIh/BN2LI763uK
JGmK2GEfgnFZ1lMdbH/uH12Ch5bPiR/TtG5DVpEI5k+q3+IJQj/OPA4vC0gbWD96
DiYqaKPj26RO87+cFvk3IfgZgEy4TrFTuW7ia34qvI0Mz9hxGOmD0gCsbM0+//kw
CVvLdckVBrkDSw/PuSGWyTBfwSfeD92A5c+1vIBP4CWHPZK2uF0BgFHT2HngezbK
Xc/thZB87whozfxcV/FIS9BIP6kD3HvJYAZgUD1Rz5GGSFgdChsZou4EV0OCpr2F
tt46iMbwzas5Ae1xL2GNb6V6VQrOK9eRHYN9lvnqJJK7d1ktjLUzNRAQl+kO+CkB
WwgQUYFZAgMBAAECggEBAKyVKgCldcfSA7HBYsAnN3dZ2Voa9c9F+NgkUGMtdGLK
vgSCrb7wesQxCvGh2zRiuu0wjHh6eiVmjsLp+HjZM+u/tappZ0fcEcIcTx0LaXvZ
5g2Lct4U6zG2sqILI1k6uoZDr2a2APKudHSeKU1y4othDMvDxyjcSQcvwZ03bKtU
cCqzfTYch5+sHjYylzYDrFH2IffU9g+jHNeErHgLcJJ7Y9ulUAHCaCVziAwJfe9r
hHxO5zjvpkAj0KpAc7819ZfPtPUNi2ZQt9DHxIwvS5yNvl1gKhpczN07SpB20Y97
V1fWa75lhQXEJOiNXz2dtKRb3tYlM7mFSIRB6ryWr4ECgYEA431uI38cmvm6iSyR
vJBd6AUCYH3gGwa00Xhjw7y4rjRtZVvIGkh6WhVklOSCbLej5MTCdlCW1t4kftsY
ObWT21ZYxrXyx1tVinI5qkRG3rN2yj8lM5FY8j9fqRuseCpK9Igx9vcCj1ntwWJq
WYiu1WFf0WJVfOmt6bulmTKJWYkCgYEA4amVVFOXmHw296+zjPIj0Vs7axjyYmW0
T6iK00Hz5qCPAa8Y1FofsZHYu6AUY5hC8FCCzecgI4v9v1dY7Bo/8Gh6B4yweI88
eZQ80tnJVyB69Ar3ZxuKfuQSjkGBFwjaUxidwaJ2+Kzif4BthoXGwdc//JUkSkh/
SE+iDp6YhVECgYEAzG1x5QocHZQesZhQmn+tM4wU17smAYNkR/yEwme8GifYysXQ
qvXIpV0mFrrGDYZ1DGZYTdQbyJi1eR3PxkRKy0br3h2xPr7vvsro0P4sJYJmVFas
Sovpvz996kyJDy8KTnZ5V/Ie5c0tX6Pd5/lxCyVG4rUYF3kypKDQrjuAu+kCgYEA
1NGpSnj3fFCRSnCCxgdKrlP7KprBZPkD3yhVnL0Td8quc+kdYo+IWl/w5aon8HGV
l6xmYCd8UOniqkSHUUvER0dQ5rPRbjGv1/1si3Hnh2rTajq5bp0ztU4FDfJK+11X
AY0yon5E82ugxJxrLrYVZ5RH/T7ulbvfhmPLszvxHbECgYBFaLiJkoqwGkiNt1Jq
brVYc5GXdZkRjK8s/7Bazc5yd9RV+GoFXloIzPYjAKbBWvT7LyLI0sMS4TF6xNKb
FoNbBBWOkGL+J2DA+ksXnFRoEGWngBEnH0/E+sRUeGT9LZPAccHCh9Z3F3aBGUEw
pRln2M5prYiiYitevKwamWX2bw==
-----END PRIVATE KEY-----
8 changes: 8 additions & 0 deletions config/keys/jwk.pub.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"kty": "RSA",
"e": "AQAB",
"use": "sig",
"kid": "sig-1645503536",
"alg": "RS256",
"n": "yIfwTdiyO-t7iiRpithhH4JxWdZTHWx_7h9dgoeWz4kf07RuQ1aRCOZPqt_iCUI_zjwOLwtIG1g_eg4mKmij49ukTvO_nBb5NyH4GYBMuE6xU7lu4mt-KryNDM_YcRjpg9IArGzNPv_5MAlby3XJFQa5A0sPz7khlskwX8En3g_dgOXPtbyAT-Alhz2StrhdAYBR09h54Hs2yl3P7YWQfO8IaM38XFfxSEvQSD-pA9x7yWAGYFA9Uc-RhkhYHQobGaLuBFdDgqa9hbbeOojG8M2rOQHtcS9hjW-lelUKzivXkR2DfZb56iSSu3dZLYy1MzUQEJfpDvgpAVsIEFGBWQ"
}
9 changes: 9 additions & 0 deletions config/keys/jwk.pub.key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyIfwTdiyO+t7iiRpithh
H4JxWdZTHWx/7h9dgoeWz4kf07RuQ1aRCOZPqt/iCUI/zjwOLwtIG1g/eg4mKmij
49ukTvO/nBb5NyH4GYBMuE6xU7lu4mt+KryNDM/YcRjpg9IArGzNPv/5MAlby3XJ
FQa5A0sPz7khlskwX8En3g/dgOXPtbyAT+Alhz2StrhdAYBR09h54Hs2yl3P7YWQ
fO8IaM38XFfxSEvQSD+pA9x7yWAGYFA9Uc+RhkhYHQobGaLuBFdDgqa9hbbeOojG
8M2rOQHtcS9hjW+lelUKzivXkR2DfZb56iSSu3dZLYy1MzUQEJfpDvgpAVsIEFGB
WQIDAQAB
-----END PUBLIC KEY-----
17 changes: 17 additions & 0 deletions config/keys/x509.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE-----
MIICsDCCAZigAwIBAgIGAX8fp163MA0GCSqGSIb3DQEBCwUAMBkxFzAVBgNVBAMM
DnNpZy0xNjQ1NTAzNTM2MB4XDTIyMDIyMjA0MTg1NloXDTIyMTIxOTA0MTg1Nlow
GTEXMBUGA1UEAwwOc2lnLTE2NDU1MDM1MzYwggEiMA0GCSqGSIb3DQEBAQUAA4IB
DwAwggEKAoIBAQDIh/BN2LI763uKJGmK2GEfgnFZ1lMdbH/uH12Ch5bPiR/TtG5D
VpEI5k+q3+IJQj/OPA4vC0gbWD96DiYqaKPj26RO87+cFvk3IfgZgEy4TrFTuW7i
a34qvI0Mz9hxGOmD0gCsbM0+//kwCVvLdckVBrkDSw/PuSGWyTBfwSfeD92A5c+1
vIBP4CWHPZK2uF0BgFHT2HngezbKXc/thZB87whozfxcV/FIS9BIP6kD3HvJYAZg
UD1Rz5GGSFgdChsZou4EV0OCpr2Ftt46iMbwzas5Ae1xL2GNb6V6VQrOK9eRHYN9
lvnqJJK7d1ktjLUzNRAQl+kO+CkBWwgQUYFZAgMBAAEwDQYJKoZIhvcNAQELBQAD
ggEBALHP5RhNqO4lw507ZTe9mWan4yMkuofMI6snKlkfpfYE3OlUtlFV8JmLFg7o
9ID7u8GuFZcKFmkiaRhW0kqOXZkr0Ks117qRbVUiESypHG21cqQXdmkXmqS99SrJ
LNLS6+leLqdOtrL6WMIxj/WL6Kc4XLhPvTM59y0Vtiv+9M5dbCvoJF6RZ5cUJAdn
V0HXGzBKG+Dcsqu0w+FOCeAMefNLMBkajtHBoJxymICeG4AoQ4rZWQNs1rJeelET
W6qyVUkPztALnOOwXWrxpNrR50FiDHx631ULaTWP30B7QBJoumQccpQqTbT05pe9
l6P798csxmfS+uDb75PkmYuz1ac=
-----END CERTIFICATE-----
10 changes: 5 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"fastify-multipart": "^5.3.1",
"fastify-session": "^5.2.1",
"fastify-swagger": "^4.0.1",
"jose": "^2.0.3",
"jose": "^4.5.0",
"jsonwebtoken": "^8.5.1",
"jwk-to-pem": "^2.0.5",
"jwt-simple": "^0.5.6",
Expand Down
5 changes: 5 additions & 0 deletions src/auth/auth.module.config.properties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,9 @@ export enum AuthModuleConfigProperties {
ENV_JWT_PUBLIC_KEY_LOCATION = 'JWT_PUBLIC_KEY_LOCATION',
ENV_JWT_SECRET_KEY = 'JWT_SECRET_KEY',
ENV_JWT_CONFIGS_URI = 'JWT_CONFIGS_URI',
ENV_JWK_PRIVATE_KEY_LOCATION = 'JWK_PRIVATE_KEY_LOCATION',
ENV_JWK_PUBLIC_KEY_LOCATION = 'JWK_PUBLIC_KEY_LOCATION',
ENV_JWK_PUBLIC_JSON = 'JWK_PUBLIC_JSON',
ENV_JKU_URL = 'JKU_URL',
ENV_X5U_URL = 'X5U_URL',
}
35 changes: 30 additions & 5 deletions src/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,32 @@ export class AuthService {
),
'utf8',
);

const jwkPrivateKey = fs.readFileSync(
this.configService.get<string>(
AuthModuleConfigProperties.ENV_JWK_PRIVATE_KEY_LOCATION,
),
'utf8',
);
const jwkPublicKey = fs.readFileSync(
this.configService.get<string>(
AuthModuleConfigProperties.ENV_JWK_PUBLIC_KEY_LOCATION,
),
'utf8',
);
const jwkPublicJson = JSON.parse(
fs.readFileSync(
this.configService.get<string>(
AuthModuleConfigProperties.ENV_JWK_PUBLIC_JSON,
),
'utf8',
),
);
const jkuUrl = this.configService.get<string>(
AuthModuleConfigProperties.ENV_JKU_URL,
);
const x5uUrl = this.configService.get<string>(
AuthModuleConfigProperties.ENV_X5U_URL,
);
const jwtSecretKey = configService.get<string>(
AuthModuleConfigProperties.ENV_JWT_SECRET_KEY,
);
Expand All @@ -68,19 +93,19 @@ export class AuthService {
);
this.processors.set(
JwtProcessorType.JKU,
new JwtTokenWithJKUProcessor(jwtSecretKey, this.httpClient),
new JwtTokenWithJKUProcessor(jwkPrivateKey, this.httpClient, jkuUrl),
);
this.processors.set(
JwtProcessorType.JWK,
new JwtTokenWithJWKProcessor(jwtSecretKey),
new JwtTokenWithJWKProcessor(jwkPrivateKey, jwkPublicJson),
);
this.processors.set(
JwtProcessorType.X5C,
new JwtTokenWithX5CKeyProcessor(jwtSecretKey),
new JwtTokenWithX5CKeyProcessor(jwkPrivateKey),
);
this.processors.set(
JwtProcessorType.X5U,
new JwtTokenWithX5UKeyProcessor(jwtSecretKey, this.httpClient),
new JwtTokenWithX5UKeyProcessor(jwkPrivateKey, this.httpClient, x5uUrl),
);

this.processors.set(
Expand Down
8 changes: 6 additions & 2 deletions src/auth/jwt/jwt.token.processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { Logger } from '@nestjs/common';
import { JwtHeader } from './jwt.header';

export abstract class JwtTokenProcessor {
private static readonly END_CERTIFICATE_MARK = '-----END PUBLIC KEY-----';
private static readonly END_CERTIFICATE_MARK = '-----END CERTIFICATE-----';
private static readonly END_PUBLIC_KEY_MARK = '-----END PUBLIC KEY-----';
protected log: Logger = new Logger(JwtTokenProcessor.name);

constructor(log: Logger) {
Expand Down Expand Up @@ -33,7 +34,10 @@ export abstract class JwtTokenProcessor {
let idx = -1;
if (
!chainText ||
(idx = chainText.indexOf(JwtTokenProcessor.END_CERTIFICATE_MARK)) == -1
(idx = Math.max(
chainText.indexOf(JwtTokenProcessor.END_CERTIFICATE_MARK),
chainText.indexOf(JwtTokenProcessor.END_PUBLIC_KEY_MARK),
)) === -1
) {
throw new Error('Invalid certificate');
}
Expand Down
24 changes: 17 additions & 7 deletions src/auth/jwt/jwt.token.with.jku.processor.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { Logger } from '@nestjs/common';
import * as jose from 'jose';
import { encode } from 'jwt-simple';
import { HttpClientService } from '../../httpclient/httpclient.service';
import { JwtTokenProcessor as JwtTokenProcessor } from './jwt.token.processor';

export class JwtTokenWithJKUProcessor extends JwtTokenProcessor {
constructor(private key: string, private httpClient: HttpClientService) {
constructor(
private key: string,
private httpClient: HttpClientService,
private jkuUrl: string,
) {
super(new Logger(JwtTokenWithJKUProcessor.name));
}

Expand All @@ -17,17 +20,24 @@ export class JwtTokenWithJKUProcessor extends JwtTokenProcessor {
}
const url = header.jku;
this.log.debug(`Calling jwk url: ${url}`);
const jwkRes = await this.httpClient.loadJSON(url);
const keyLike = await jose.JWK.asKey(JSON.stringify(jwkRes));
const verifyRes = await jose.JWT.verify(token, keyLike);
const jwkRes: jose.JWK = await this.httpClient.loadJSON(url);
const keyLike = await jose.importJWK(jwkRes);
const verifyRes = await jose.jwtVerify(token, keyLike);
if (verifyRes) {
return payload;
}
throw new Error('Could not validate');
}

async createToken(payload: unknown): Promise<string> {
async createToken(payload: jose.JWTPayload): Promise<string> {
this.log.debug('Call createToken');
return encode(payload, this.key, 'HS256');
const pkcs8 = await jose.importPKCS8(this.key, 'RS256');
return new jose.SignJWT(payload)
.setProtectedHeader({
typ: 'JWT',
alg: 'RS256',
jku: this.jkuUrl,
})
.sign(pkcs8);
}
}
18 changes: 12 additions & 6 deletions src/auth/jwt/jwt.token.with.jwk.processor.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { Logger } from '@nestjs/common';
import * as jose from 'jose';
import { encode } from 'jwt-simple';
import { JwtTokenProcessor as JwtTokenProcessor } from './jwt.token.processor';

export class JwtTokenWithJWKProcessor extends JwtTokenProcessor {
constructor(private key: string) {
constructor(private key: string, private jwk: jose.JWK) {
super(new Logger(JwtTokenWithJWKProcessor.name));
}

Expand All @@ -21,18 +20,25 @@ export class JwtTokenWithJWKProcessor extends JwtTokenProcessor {
if (!header.jwk.kty) {
return payload;
}
const keyLike = await jose.JWK.asKey(JSON.stringify(header.jwk));
const keyLike = await jose.importJWK(header.jwk);

const res = await jose.JWT.verify(token, keyLike);
const res = await jose.jwtVerify(token, keyLike);

if (res) {
return payload;
}
throw new Error('Could not validate token');
}

async createToken(payload: unknown): Promise<string> {
async createToken(payload: jose.JWTPayload): Promise<string> {
this.log.debug('Call createToken');
return encode(payload, this.key, 'HS256');
const pkcs8 = await jose.importPKCS8(this.key, 'RS256');
return new jose.SignJWT(payload)
.setProtectedHeader({
typ: 'JWT',
alg: 'RS256',
jwk: this.jwk,
})
.sign(pkcs8);
}
}
16 changes: 12 additions & 4 deletions src/auth/jwt/jwt.token.with.x5c.key.processor.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Logger } from '@nestjs/common';
import { decode, encode } from 'jwt-simple';
import * as jose from 'jose';
import { JwtTokenProcessor as JwtTokenProcessor } from './jwt.token.processor';

export class JwtTokenWithX5CKeyProcessor extends JwtTokenProcessor {
Expand All @@ -14,12 +14,20 @@ export class JwtTokenWithX5CKeyProcessor extends JwtTokenProcessor {
return payload;
}
const keys = header.x5c;
const keyLike = await jose.importPKCS8(keys[0], 'RS256');
this.log.debug(`Taking keys from ${JSON.stringify(keys)}`);
return decode(token, keys[0], false, header.alg);
return await jose.jwtVerify(token, keyLike);
}

async createToken(payload: unknown): Promise<string> {
async createToken(payload: jose.JWTPayload): Promise<string> {
this.log.debug('Call createToken');
return encode(payload, this.key, 'HS256');
const pkcs8 = await jose.importPKCS8(this.key, 'RS256');
return new jose.SignJWT(payload)
.setProtectedHeader({
typ: 'JWT',
alg: 'RS256',
x5c: [this.key],
})
.sign(pkcs8);
}
}
25 changes: 19 additions & 6 deletions src/auth/jwt/jwt.token.with.x5u.key.processor.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { Logger } from '@nestjs/common';
import { decode, encode } from 'jwt-simple';
import * as jose from 'jose';
import { HttpClientService } from '../../httpclient/httpclient.service';
import { JwtTokenProcessor as JwtTokenProcessor } from './jwt.token.processor';

export class JwtTokenWithX5UKeyProcessor extends JwtTokenProcessor {
constructor(private key: string, private httpClient: HttpClientService) {
constructor(
private key: string,
private httpClient: HttpClientService,
private x5uUrl: string,
) {
super(new Logger(JwtTokenWithX5UKeyProcessor.name));
}

Expand All @@ -17,11 +20,21 @@ export class JwtTokenWithX5UKeyProcessor extends JwtTokenProcessor {
const url = header.x5u;
this.log.debug(`Loading key from url ${url}`);
const crtPayload = await this.httpClient.loadPlain(url);
return decode(token, this.parseCRTChain(crtPayload), false, header.alg);
const x509 = await jose.importX509(crtPayload, 'RS256');

return jose.jwtVerify(token, x509);
}

async createToken(payload: unknown): Promise<string> {
async createToken(payload: jose.JWTPayload): Promise<string> {
this.log.debug('Call createToken');
return encode(payload, this.key, 'HS256');

const pkcs8 = await jose.importPKCS8(this.key, 'RS256');
return new jose.SignJWT(payload)
.setProtectedHeader({
typ: 'JWT',
alg: 'RS256',
x5u: this.x5uUrl,
})
.sign(pkcs8);
}
}

0 comments on commit 55e99c9

Please sign in to comment.