github.com/phrase/openapi@v0.0.0-20240514140800-49e8a106740e/openapi-generator/templates/java/libraries/jersey2-experimental/auth/HttpSignatureAuth.mustache (about) 1 {{>licenseInfo}} 2 3 package {{invokerPackage}}.auth; 4 5 import {{invokerPackage}}.Pair; 6 import {{invokerPackage}}.ApiException; 7 8 import java.net.URI; 9 import java.net.URLEncoder; 10 import java.security.MessageDigest; 11 import java.security.Key; 12 import java.text.SimpleDateFormat; 13 import java.util.ArrayList; 14 import java.util.Base64; 15 import java.util.Date; 16 import java.util.Locale; 17 import java.util.Map; 18 import java.util.List; 19 20 import org.tomitribe.auth.signatures.*; 21 22 /** 23 * A Configuration object for the HTTP message signature security scheme. 24 */ 25 public class HttpSignatureAuth implements Authentication { 26 27 private Signer signer; 28 29 // An opaque string that the server can use to look up the component they need to validate the signature. 30 private String keyId; 31 32 // The HTTP signature algorithm. 33 private Algorithm algorithm; 34 35 // The list of HTTP headers that should be included in the HTTP signature. 36 private List<String> headers; 37 38 // The digest algorithm which is used to calculate a cryptographic digest of the HTTP request body. 39 private String digestAlgorithm; 40 41 /** 42 * Construct a new HTTP signature auth configuration object. 43 * 44 * @param keyId An opaque string that the server can use to look up the component they need to validate the signature. 45 * @param algorithm The signature algorithm. 46 * @param headers The list of HTTP headers that should be included in the HTTP signature. 47 */ 48 public HttpSignatureAuth(String keyId, Algorithm algorithm, List<String> headers) { 49 this.keyId = keyId; 50 this.algorithm = algorithm; 51 this.headers = headers; 52 this.digestAlgorithm = "SHA-256"; 53 } 54 55 /** 56 * Returns the opaque string that the server can use to look up the component they need to validate the signature. 57 * 58 * @return The keyId. 59 */ 60 public String getKeyId() { 61 return keyId; 62 } 63 64 /** 65 * Set the HTTP signature key id. 66 * 67 * @param keyId An opaque string that the server can use to look up the component they need to validate the signature. 68 */ 69 public void setKeyId(String keyId) { 70 this.keyId = keyId; 71 } 72 73 /** 74 * Returns the HTTP signature algorithm which is used to sign HTTP requests. 75 */ 76 public Algorithm getAlgorithm() { 77 return algorithm; 78 } 79 80 /** 81 * Sets the HTTP signature algorithm which is used to sign HTTP requests. 82 * 83 * @param algorithm The HTTP signature algorithm. 84 */ 85 public void setAlgorithm(Algorithm algorithm) { 86 this.algorithm = algorithm; 87 } 88 89 /** 90 * Returns the digest algorithm which is used to calculate a cryptographic digest of the HTTP request body. 91 * 92 * @see java.security.MessageDigest 93 */ 94 public String getDigestAlgorithm() { 95 return digestAlgorithm; 96 } 97 98 /** 99 * Sets the digest algorithm which is used to calculate a cryptographic digest of the HTTP request body. 100 * 101 * The exact list of supported digest algorithms depends on the installed security providers. 102 * Every implementation of the Java platform is required to support "MD5", "SHA-1" and "SHA-256". 103 * Do not use "MD5" and "SHA-1", they are vulnerable to multiple known attacks. 104 * By default, "SHA-256" is used. 105 * 106 * @param digestAlgorithm The digest algorithm. 107 * 108 * @see java.security.MessageDigest 109 */ 110 public void setDigestAlgorithm(String digestAlgorithm) { 111 this.digestAlgorithm = digestAlgorithm; 112 } 113 114 /** 115 * Returns the list of HTTP headers that should be included in the HTTP signature. 116 */ 117 public List<String> getHeaders() { 118 return headers; 119 } 120 121 /** 122 * Sets the list of HTTP headers that should be included in the HTTP signature. 123 * 124 * @param headers The HTTP headers. 125 */ 126 public void setHeaders(List<String> headers) { 127 this.headers = headers; 128 } 129 130 public Signer getSigner() { 131 return signer; 132 } 133 134 public void setSigner(Signer signer) { 135 this.signer = signer; 136 } 137 138 /** 139 * Set the private key used to sign HTTP requests using the HTTP signature scheme. 140 * 141 * @param key The private key. 142 */ 143 public void setPrivateKey(Key key) throws ApiException { 144 if (key == null) { 145 throw new ApiException("Private key (java.security.Key) cannot be null"); 146 } 147 148 signer = new Signer(key, new Signature(keyId, algorithm, null, headers)); 149 } 150 151 @Override 152 public void applyToParams(List<Pair> queryParams, Map<String, String> headerParams, Map<String, String> cookieParams, 153 String payload, String method, URI uri) throws ApiException { 154 try { 155 if (headers.contains("host")) { 156 headerParams.put("host", uri.getHost()); 157 } 158 159 if (headers.contains("date")) { 160 headerParams.put("date", new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US).format(new Date())); 161 } 162 163 if (headers.contains("digest")) { 164 headerParams.put("digest", 165 this.digestAlgorithm + "=" + 166 new String(Base64.getEncoder().encode(MessageDigest.getInstance(this.digestAlgorithm).digest(payload.getBytes())))); 167 } 168 169 if (signer == null) { 170 throw new ApiException("Signer cannot be null. Please call the method `setPrivateKey` to set it up correctly"); 171 } 172 173 // construct the path with the URL query string 174 String path = uri.getPath(); 175 176 List<String> urlQueries = new ArrayList<String>(); 177 for (Pair queryParam : queryParams) { 178 urlQueries.add(queryParam.getName() + "=" + URLEncoder.encode(queryParam.getValue(), "utf8").replaceAll("\\+", "%20")); 179 } 180 181 if (!urlQueries.isEmpty()) { 182 path = path + "?" + String.join("&", urlQueries); 183 } 184 185 headerParams.put("Authorization", signer.sign(method, path, headerParams).toString()); 186 } catch (Exception ex) { 187 throw new ApiException("Failed to create signature in the HTTP request header: " + ex.toString()); 188 } 189 } 190 }