JwtHeaders.java
- /*
- * GovWay - A customizable API Gateway
- * https://govway.org
- *
- * Copyright (c) 2005-2025 Link.it srl (https://link.it).
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 3, as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
- package org.openspcoop2.utils.security;
- import java.net.URI;
- import java.security.cert.X509Certificate;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.Iterator;
- import java.util.List;
- import org.apache.cxf.common.util.Base64UrlUtility;
- import org.apache.cxf.rs.security.jose.common.KeyManagementUtils;
- import org.apache.cxf.rs.security.jose.jwk.JsonWebKey;
- import org.apache.cxf.rs.security.jose.jwk.JsonWebKeys;
- import org.apache.cxf.rs.security.jose.jwk.JwkUtils;
- import org.apache.cxf.rt.security.crypto.MessageDigestUtils;
- import org.openspcoop2.utils.UtilsException;
- /**
- * JwtHeaders
- *
- * @author Poli Andrea (apoli@link.it)
- * @author $Author$
- * @version $Rev$, $Date$
- */
- public class JwtHeaders {
- public static final String JWT_HDR_ALG = "alg"; // (Algorithm) Header Parameter
- public static final String JWT_HDR_JKU = "jku"; // (JWK Set URL) Header Parameter
- public static final String JWT_HDR_JWK = "jwk"; // (JSON Web Key) Header Parameter
- public static final String JWT_HDR_KID = "kid"; // (Key ID) Header Parameter
- public static final String JWT_HDR_X5U = "x5u"; // (X.509 URL) Header Parameter
- public static final String JWT_HDR_X5C = "x5c"; // (X.509 Certificate Chain) Header Parameter
- public static final String JWT_HDR_X5T = "x5t"; // (X.509 Certificate SHA-1 Thumbprint) Header Parameter
- public static final String JWT_HDR_X5t_S256 = "x5t#S256"; // (X.509 Certificate SHA-256 Thumbprint) Header Parameter
- public static final String JWT_HDR_TYP = "typ"; // (Type) Header Parameter
- public static final String JWT_HDR_CTY = "cty"; // (Content Type) Header Parameter
- public static final String JWT_HDR_CRIT = "crit"; // (Critical) Header Parameter
- public static final String JWT_HDR_ENC = "enc"; // (Encryption Algorithm) Header Parameter [solo in jwe]
- public static final String JWT_HDR_ZIP = "zip"; // (Compression Algorithm) Header Parameter [solo in jwe]
-
- private String type;
- private String contentType;
- private String kid;
- private List<String> criticalHeaders = new ArrayList<>();
- private URI x509Url;
- private List<X509Certificate> x509c = new ArrayList<>(); // i certificati servono anche per sha1 e sha256, il field addX5C serve quindi per capire se poi far uscire anche X5C
- private boolean addX5C = false;
- boolean x509IncludeCertSha1 = false;
- boolean x509IncludeCertSha256 = false;
- private URI jwkUrl;
- private JsonWebKey jwKey;
- private HashMap<String, String> extensions = new HashMap<>();
-
- public void setType(String type) {
- this.type = type;
- }
- public void setContentType(String contentType) {
- this.contentType = contentType;
- }
- public String getKid() {
- return this.kid;
- }
- public void addCriticalHeader(String hdr) {
- this.criticalHeaders.add(hdr);
- }
- public void setX509Url(URI x509Url) {
- this.x509Url = x509Url;
- }
- public void addX509cert(X509Certificate x509c) {
- this.x509c.add(x509c);
- }
- public void setAddX5C(boolean addX5C) {
- this.addX5C = addX5C;
- }
- public boolean isX509IncludeCertSha1() {
- return this.x509IncludeCertSha1;
- }
- public boolean isX509IncludeCertSha256() {
- return this.x509IncludeCertSha256;
- }
- public void setJwkUrl(URI jwkUrl) {
- this.jwkUrl = jwkUrl;
- }
- public void setJwKey(JsonWebKey jwKey) {
- this.jwKey = jwKey;
- }
- public void setJwKey(JsonWebKeys jsonWebKeys, String alias) throws UtilsException {
- this.jwKey = JsonUtils.readKey(jsonWebKeys, alias);
- }
- public void addExtension(String hdr, String value) {
- this.extensions.put(hdr, value);
- }
-
- public String getType() {
- return this.type;
- }
- public String getContentType() {
- return this.contentType;
- }
- public void setKid(String kid) {
- this.kid = kid;
- }
- public List<String> getCriticalHeaders() {
- return this.criticalHeaders;
- }
- public URI getX509Url() {
- return this.x509Url;
- }
- public boolean isAddX5C() {
- return this.addX5C;
- }
- public List<X509Certificate> getX509c() {
- return this.x509c;
- }
- public void setX509IncludeCertSha1(boolean includeCertSha1) {
- this.x509IncludeCertSha1 = includeCertSha1;
- }
- public void setX509IncludeCertSha256(boolean includeCertSha256) {
- this.x509IncludeCertSha256 = includeCertSha256;
- }
- public URI getJwkUrl() {
- return this.jwkUrl;
- }
- public JsonWebKey getJwKey() {
- return this.jwKey;
- }
- public HashMap<String, String> getExtensions() {
- return this.extensions;
- }
-
- public List<String> headers(){
- List<String> list = new ArrayList<>();
- if(this.type!=null) {
- list.add(JWT_HDR_TYP);
- }
- if(this.contentType!=null) {
- list.add(JWT_HDR_CTY);
- }
- if(this.kid!=null) {
- list.add(JWT_HDR_KID);
- }
- if(this.criticalHeaders!=null && !this.criticalHeaders.isEmpty()) {
- list.add(JWT_HDR_CRIT);
- }
- if(this.x509Url!=null) {
- list.add(JWT_HDR_X5U);
- }
- if(this.x509c!=null && !this.x509c.isEmpty()) {
- // fix: lo aggiungo solo se non c'è la url. Nell'oggetto JwtHreader il certificato ho dovuto mettercelo per creare i sha
- //if(!list.contains(JWT_HDR_X5U)) {
- // il fix era errato, aggiunto field apposito 'addX5C'
- if(this.addX5C) {
- list.add(JWT_HDR_X5C);
- }
- }
- if(this.x509IncludeCertSha1 && this.x509c!=null && !this.x509c.isEmpty()) {
- list.add(JWT_HDR_X5T);
- }
- if(this.x509IncludeCertSha256) {
- list.add(JWT_HDR_X5t_S256);
- }
- if(this.jwkUrl!=null) {
- list.add(JWT_HDR_JKU);
- }
- if(this.jwKey!=null) {
- list.add(JWT_HDR_JWK);
- }
- if(this.extensions!=null && !this.extensions.isEmpty()) {
- Iterator<String> hdrIt = this.extensions.keySet().iterator();
- while (hdrIt.hasNext()) {
- String hdr = (String) hdrIt.next();
- list.add(hdr);
- }
- }
- return list;
- }
-
- public void fillJwsHeaders(org.apache.cxf.rs.security.jose.common.JoseHeaders hdrs, boolean forceOverride, String algorithm) throws Exception {
- if(this.type!=null) {
- if(!hdrs.containsHeader(JWT_HDR_TYP) || forceOverride) {
- hdrs.setHeader(JWT_HDR_TYP, this.type);
- }
- }
- if(this.contentType!=null) {
- if(!hdrs.containsHeader(JWT_HDR_CTY) || forceOverride) {
- hdrs.setContentType(this.contentType);
- }
- }
- if(this.kid!=null) {
- if(!hdrs.containsHeader(JWT_HDR_KID) || forceOverride) {
- hdrs.setKeyId(this.kid);
- }
- }
- if(this.criticalHeaders!=null && !this.criticalHeaders.isEmpty()) {
- List<String> headers = new ArrayList<>();
- if(hdrs.containsHeader(JWT_HDR_CRIT)) {
- headers = hdrs.getCritical();
- if(headers==null) {
- headers = new ArrayList<>();
- }
- }
- for (String ch : this.criticalHeaders) {
- if(headers.contains(ch)==false) {
- headers.add(ch);
- }
- }
- /*
- StringBuilder bf = new StringBuilder();
- for (String ch : headers) {
- if(bf.length()>0) {
- bf.append(",");
- }
- bf.append("\"").append(ch).append("\"");
- }
- hdrs.setHeader(JWT_HDR_CRIT, "["+bf.toString()+"]");*/
- hdrs.setCritical(headers);
- }
- if(this.x509Url!=null) {
- if(!hdrs.containsHeader(JWT_HDR_X5U) || forceOverride) {
- hdrs.setX509Url(this.x509Url.toString());
- }
- }
- if(this.x509c!=null && !this.x509c.isEmpty()) {
- if(!hdrs.containsHeader(JWT_HDR_X5C) || forceOverride) {
- // fix: lo aggiungo solo se non c'è la url. Nell'oggetto JwtHreader il certificato ho dovuto mettercelo per creare i sha
- //if(!hdrs.containsHeader(JWT_HDR_X5U)) {
- // il fix era errato, aggiunto field apposito 'addX5C'
- if(this.addX5C) {
- X509Certificate[] chain = this.x509c.toArray(new X509Certificate[1]);
- hdrs.setX509Chain(KeyManagementUtils.encodeX509CertificateChain(chain));
- }
- }
- }
- if(this.x509IncludeCertSha1 && this.x509c!=null && !this.x509c.isEmpty()) {
- if(!hdrs.containsHeader(JWT_HDR_X5T) || forceOverride) {
- X509Certificate[] chain = this.x509c.toArray(new X509Certificate[1]);
- byte[] digestB = MessageDigestUtils.createDigest(chain[0].getEncoded(), MessageDigestUtils.ALGO_SHA_1);
- String digest = Base64UrlUtility.encode(digestB);
- hdrs.setX509Thumbprint(digest);
- }
- }
- if(this.x509IncludeCertSha256) {
- if(!hdrs.containsHeader(JWT_HDR_X5t_S256) || forceOverride) {
- X509Certificate[] chain = this.x509c.toArray(new X509Certificate[1]);
- byte[] digestB = MessageDigestUtils.createDigest(chain[0].getEncoded(), MessageDigestUtils.ALGO_SHA_256);
- String digest = Base64UrlUtility.encode(digestB);
- hdrs.setX509ThumbprintSHA256(digest);
- }
- }
- if(this.jwkUrl!=null) {
- if(!hdrs.containsHeader(JWT_HDR_JKU) || forceOverride) {
- hdrs.setJsonWebKeysUrl(this.jwkUrl.toString());
- }
- }
- if(this.jwKey!=null) {
- if(!hdrs.containsHeader(JWT_HDR_JWK) || forceOverride) {
- JwkUtils.includeCertChain(this.jwKey, hdrs, algorithm);
- JwkUtils.includePublicKey(this.jwKey, hdrs, algorithm);
- }
- }
- if(this.extensions!=null && !this.extensions.isEmpty()) {
- Iterator<String> hdrIt = this.extensions.keySet().iterator();
- while (hdrIt.hasNext()) {
- String hdr = (String) hdrIt.next();
- if(!hdrs.containsHeader(hdr) || forceOverride) {
- String value = this.extensions.get(hdr);
- hdrs.setHeader(hdr,value);
- }
- }
- }
- }
-
- }