Firma de tokens jwt propios para las solicitues
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import { sign } from "node:crypto"
|
||||
|
||||
export type JWTHeader = {
|
||||
alg: string,
|
||||
typ: string,
|
||||
@@ -42,6 +44,20 @@ export type JWT<T> = {
|
||||
signature: JWTSignature
|
||||
}
|
||||
|
||||
// todo pasar a la clase JWT
|
||||
function signJWT(args: {
|
||||
algorythm: "sha256" | string,
|
||||
data: string,
|
||||
privateKey: string
|
||||
}) {
|
||||
const signature = sign(
|
||||
args.algorythm,
|
||||
Buffer.from(args.data),
|
||||
args.privateKey
|
||||
)
|
||||
return signature
|
||||
}
|
||||
|
||||
export class JWTToken<T> {
|
||||
|
||||
public rawToken: string
|
||||
@@ -54,6 +70,37 @@ export class JWTToken<T> {
|
||||
this.decodedPayload = this.decodePayload()
|
||||
}
|
||||
|
||||
public static fromParts<T>(args: {
|
||||
header: JWTHeader,
|
||||
payload?: JWTPayload<T>,
|
||||
sigantureData?: {
|
||||
privateKey: string,
|
||||
algorythm: string
|
||||
}
|
||||
}) {
|
||||
const strHeader = JSON.stringify(args.header)
|
||||
const base64Header = Buffer.from(strHeader).toString("base64url")
|
||||
let msg = base64Header
|
||||
|
||||
if (args.payload != undefined) {
|
||||
const strPayload = JSON.stringify(args.payload)
|
||||
const base64payload = Buffer.from(strPayload).toString("base64url")
|
||||
msg += ("." + base64payload)
|
||||
}
|
||||
|
||||
if (args.sigantureData != undefined) {
|
||||
const base64signature = signJWT({
|
||||
algorythm: args.sigantureData.algorythm,
|
||||
privateKey: args.sigantureData.privateKey,
|
||||
data: msg
|
||||
}).toString("base64url")
|
||||
msg += ("." + base64signature)
|
||||
}
|
||||
console.log("JWT", msg)
|
||||
|
||||
|
||||
}
|
||||
|
||||
private decodePayload(): JWTPayload<T> {
|
||||
if (this.rawToken == undefined) throw new Error("La clase no tiene un token definido")
|
||||
const rawTokenPayload = this.rawToken.split(".")[1]
|
||||
|
||||
@@ -3,3 +3,4 @@ OBJ_PEM_PATH=./obj.pem
|
||||
OBJ_AUTHORIZATION=XOc7FtwXD8hUX2SFVX94XSty8wkOmChkwDNF09O_aIxPubMDdFUdCDCB4zpzSIxi8nOcTg7r_LM_nmd5qm7uLbksf_XArjI8iAyhjKz_2BAXPhmvKs4Fc9f3vv5LDfCVrPB9lP8P7rJ66_qnWs4jvhLQxSfn29m96hgXeCf8oySdIDUjN2q9Js3KAS5LL52Ri6ryvUeO1PvMhaPQMWRqoHIqTV1wPfPtiqQwcjUPmu5GeW164Kq1JLgV3KaGzfCZ9Qv9lbv30EJrukXxWuLCAhBS0kzrBXZoWvf2pb9uh3Am_93_dDxiIGQfIap9ZU_m8ZD1HPgvZOMCY6ZkxQconQ
|
||||
OBJ_CLI_ASSERTION=XOc7FtwXD8hUX2SFVX94XSty8wkOmChkwDNF09O_aIxPubMDdFUdCDCB4zpzSIxi8nOcTg7r_LM_nmd5qm7uLbksf_XArjI8iAyhjKz_2BAXPhmvKs4Fc9f3vv5LDfCVrPB9lP8P7rJ66_qnWs4jvhLQxSfn29m96hgXeCf8oySdIDUjN2q9Js3KAS5LL52Ri6ryvUeO1PvMhaPQMWRqoHIqTV1wPfPtiqQwcjUPmu5GeW164Kq1JLgV3KaGzfCZ9Qv9lbv30EJrukXxWuLCAhBS0kzrBXZoWvf2pb9uh3Am_93_dDxiIGQfIap9ZU_m8ZD1HPgvZOMCY6ZkxQconQ
|
||||
OBJ_CLIENT_ID=savefamily_rest_ws
|
||||
OBJ_KID=xNfbMiyL1ORXGP8lElhcv8nVaG3EJKye4Lc1YoN3I1E
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { test, describe } from "vitest"
|
||||
import { JWTService } from "./JWT.service"
|
||||
import { loadEnvFile } from "node:process"
|
||||
|
||||
describe("Tokens Objenious", () => {
|
||||
const jwtService = new JWTService()
|
||||
@@ -9,7 +8,7 @@ describe("Tokens Objenious", () => {
|
||||
console.log("test env", process.env.OBJ_CLIENT_ID)
|
||||
|
||||
test("Solicicitud normal de auth", async () => {
|
||||
//const token = await jwtService.getAccessToken()
|
||||
|
||||
const token = await jwtService.getAccessToken()
|
||||
console.log("acceso objenious", token)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
// PEM ?
|
||||
|
||||
import { env } from "#config/env";
|
||||
import fs from "fs"
|
||||
|
||||
import {
|
||||
JWTToken
|
||||
} from "#shared/domain/JWT"
|
||||
import axios from "axios";
|
||||
import axios, { AxiosError } from "axios";
|
||||
import { sign } from "node:crypto"
|
||||
|
||||
type GrantAccessRequestBody = {
|
||||
grant_type: string,
|
||||
@@ -23,9 +25,19 @@ type TokensRequestResponse = {
|
||||
"not-before-policy": number,
|
||||
"session_state": string,
|
||||
"scope": string
|
||||
|
||||
}
|
||||
|
||||
type AuthHeaders = {
|
||||
content_type: string,
|
||||
sub: string,
|
||||
iss: string,
|
||||
aud: string,
|
||||
jti: string,
|
||||
iat: number,
|
||||
exp: number,
|
||||
}
|
||||
|
||||
|
||||
const GET_TOKEN_URL = "https://idp.docapost.io/auth/realms/GETWAY/protocol/openid-connect/token"
|
||||
const REFRESH_TOKEN_URL = GET_TOKEN_URL
|
||||
|
||||
@@ -45,6 +57,20 @@ const DEFAULT_HEADERS = {
|
||||
"content-type": "application/x-www-form-urlencoded"
|
||||
}
|
||||
|
||||
function addIATHeaders(authHeaders: Object) {
|
||||
const headers = <AuthHeaders>{
|
||||
...authHeaders,
|
||||
sub: env.OBJ_CLIENT_ID,
|
||||
iss: env.OBJ_CLIENT_ID,
|
||||
aud: GET_TOKEN_URL,
|
||||
jti: Date.now().toString(),
|
||||
iat: Math.floor(Date.now() / 1000),
|
||||
exp: Math.floor(Date.now() / 1000) + 5 * 60,
|
||||
}
|
||||
return headers
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* El servicio gestiona un par de tokens auth - refresh para las
|
||||
* operaciones de Objenious.
|
||||
@@ -69,12 +95,40 @@ export class JWTService {
|
||||
console.warn("Se está intentado conseguir un token sin expirar el anterior")
|
||||
}
|
||||
|
||||
console.log("headers", addIATHeaders(DEFAULT_HEADERS))
|
||||
console.log("body", DEFAULT_BODY)
|
||||
console.log("keypath", __dirname + "/../obj.pem")
|
||||
const key = fs.readFileSync(__dirname + "/../obj.pem", "utf8")
|
||||
const msg = Buffer.from("test")
|
||||
const signature = sign(
|
||||
"sha256",
|
||||
Buffer.from(msg),
|
||||
key
|
||||
)
|
||||
JWTToken.fromParts({
|
||||
header: { alg: "RS256", typ: "JWT", kid: "1234" },
|
||||
payload: {
|
||||
"iss": "savefamily_rest_ws",
|
||||
"aud": "https://idp.docapost.io/auth/realms/GETWAY",
|
||||
},
|
||||
sigantureData: {
|
||||
algorythm: "sha256",
|
||||
privateKey: key
|
||||
}
|
||||
})
|
||||
console.log("signature", signature.toString("base64url"))
|
||||
|
||||
return;
|
||||
|
||||
const req = axios.post(GET_TOKEN_URL,
|
||||
DEFAULT_BODY,
|
||||
{
|
||||
headers: DEFAULT_HEADERS
|
||||
headers: addIATHeaders(DEFAULT_HEADERS)
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
|
||||
let res;
|
||||
|
||||
try {
|
||||
@@ -84,7 +138,7 @@ export class JWTService {
|
||||
return this.authToken
|
||||
} catch (e) {
|
||||
const errorString = "No se ha podido conseguir el token de acceso de OBJENIOUS"
|
||||
console.error(errorString, e)
|
||||
console.error(errorString, (e as AxiosError).response?.data)
|
||||
throw new Error(errorString)
|
||||
}
|
||||
|
||||
|
||||
@@ -26,8 +26,8 @@ export const env = {
|
||||
OBJ_PEM_PATH: String(process.env.OBJ_PEM_PATH),
|
||||
OBJ_AUTHOIZATION: String(process.env.OBJ_ATHORIZATION),
|
||||
OBJ_CLI_ASSERTION: String(process.env.OBJ_CLI_ASSERTION),
|
||||
OBJ_CLIENT_ID: String(process.env.OBJ_CLIENT_ID)
|
||||
OBJ_CLIENT_ID: String(process.env.OBJ_CLIENT_ID),
|
||||
OBJ_KID: String(process.env.OBJ_KID)
|
||||
|
||||
};
|
||||
|
||||
console.log("env", env)
|
||||
|
||||
6
packages/sim-consumidor-activaciones/mykey.pub
Normal file
6
packages/sim-consumidor-activaciones/mykey.pub
Normal file
@@ -0,0 +1,6 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDIeBiNCOYvDODs8ruiJzTAiBgW
|
||||
IiYbKdJf5fyX56tUhXhSHqG53nK0U9xgBFZY2y3DBXNnE9Sl9lXYdAo8kULtXTT4
|
||||
3Krcwb1mmbg3ofVliyGaLSymtSJGHfTKG2VMUf6EBkjnNKn279h7xnK+xvKb7KrK
|
||||
vNPaK2KZllMX7ITRnwIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
9
packages/sim-consumidor-activaciones/obj.pub
Normal file
9
packages/sim-consumidor-activaciones/obj.pub
Normal file
@@ -0,0 +1,9 @@
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4aJ+D7qw+PI0Pa/0BKz4
|
||||
1Y6ihP7FLBBag93KPeo1SEjinXyVTfFmxeTxOEhUvsomIA1E5QounKD6i3H83bX/
|
||||
+KMm0GgpT+9OjbkEWF8a7+kMGXokilE/9Ah9uwBBzXCzJl4YUyE2VhDQUG6nYCj2
|
||||
0XH8bSbtdEb5cUeFA6ZTMm3wYddmfJjKTtZvz4yiyLO8HjW2+1H32rQ0Sr0d7mPD
|
||||
ch0zm4kBjG4kVXgSUnfk68TgUVNTwikxEQfJ5fb+AME0HOA9mgiGdyKgdNIsd4IP
|
||||
2zgenWpniAPbGfth6sO78+vrETw/Ul42dgxpxejLfgDhqgrTPbi7zFomh61WFVJO
|
||||
zQIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
Reference in New Issue
Block a user