1 /* 2 * The contents of this file are subject to the terms of the Common Development and 3 * Distribution License (the License). You may not use this file except in compliance with the 4 * License. 5 * 6 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 7 * specific language governing permission and limitations under the License. 8 * 9 * When distributing Covered Software, include this CDDL Header Notice in each file and include 10 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 11 * Header, with the fields enclosed by brackets [] replaced by your own identifying 12 * information: "Portions copyright [year] [name of copyright owner]". 13 * 14 * Copyright 2013-2015 ForgeRock AS. 15 */ 16 17 package org.forgerock.json.jose.jwt; 18 19 import static org.forgerock.json.jose.jwt.JwtHeaderKey.ALG; 20 import static org.forgerock.json.jose.jwt.JwtHeaderKey.TYP; 21 import static org.forgerock.json.jose.jwt.JwtHeaderKey.getHeaderKey; 22 23 import java.util.Map; 24 25 /** 26 * A base implementation class for JWT Headers. 27 * <p> 28 * Provides methods to set header parameters for all types of JWT Headers. 29 * 30 * @see org.forgerock.json.jose.jws.JwsHeader 31 * @see org.forgerock.json.jose.jwe.JweHeader 32 * 33 * @since 2.0.0 34 */ 35 public abstract class JwtHeader extends JWObject { 36 37 /** 38 * Constructs a new JwtHeader, with the "typ" parameter set to "JWT". 39 */ 40 public JwtHeader() { 41 put(TYP.value(), JwtType.JWT.toString()); 42 } 43 44 /** 45 * Constructs a new JwtHeader, with its parameters set to the contents of the given Map. 46 * 47 * @param headers A Map containing the parameters to be set in the header. 48 */ 49 public JwtHeader(Map<String, Object> headers) { 50 this(); 51 setParameters(headers); 52 } 53 54 /** 55 * Sets the type of JWT this header represents. 56 * <p> 57 * For non-nested JWTs then the "JWT" type is RECOMMENDED to be used but it is OPTIONAL to set the "typ" property. 58 * For nested signed or encrypted JWTs the JWT type MUST be "JWS" and "JWE" respectively and the "typ" property 59 * MUST be set. 60 * 61 * @see JwtType 62 * 63 * @param jwtType The JwtType. 64 */ 65 public void setType(JwtType jwtType) { 66 put(TYP.value(), jwtType.toString()); 67 } 68 69 /** 70 * Gets the type of JWT this header represents. 71 * 72 * @return The JwtType. 73 */ 74 public JwtType getType() { 75 return JwtType.valueOf(get(TYP.value()).asString().toUpperCase()); 76 } 77 78 /** 79 * Sets the algorithm used to perform cryptographic signing and/or encryption on the JWT. 80 * 81 * @param algorithm The Algorithm. 82 */ 83 public void setAlgorithm(Algorithm algorithm) { 84 put(ALG.value(), algorithm.toString()); 85 } 86 87 /** 88 * Gets the Algorithm set in the JWT header. 89 * 90 * @return The Algorithm. 91 */ 92 public abstract Algorithm getAlgorithm(); 93 94 /** 95 * Gets the string representation of the Algorithm set in the JWT header. 96 * 97 * @return The algorithm as a String. 98 */ 99 protected String getAlgorithmString() { 100 return get(ALG.value()).asString(); 101 } 102 103 /** 104 * Sets a header parameter with the specified key and value. 105 * <p> 106 * If the key matches one of the reserved header parameter names, then the relevant <tt>set</tt> method is 107 * called to set that header parameter with the specified value. 108 * 109 * @param key The key of the header parameter. 110 * @param value The value of the header parameter. 111 */ 112 public void setParameter(String key, Object value) { 113 JwtHeaderKey headerKey = getHeaderKey(key.toUpperCase()); 114 115 switch (headerKey) { 116 case TYP: { 117 if (isValueOfType(value, JwtType.class)) { 118 setType((JwtType) value); 119 } else { 120 checkValueIsOfType(value, String.class); 121 setType(JwtType.jwtType((String) value)); 122 } 123 break; 124 } 125 case ALG: { 126 if (isValueOfType(value, Algorithm.class)) { 127 setAlgorithm((Algorithm) value); 128 } else { 129 checkValueIsOfType(value, String.class); 130 put(ALG.value(), value); 131 } 132 break; 133 } 134 default: { 135 put(key, value); 136 } 137 } 138 } 139 140 /** 141 * Sets header parameters using the values contained in the specified map. 142 * 143 * @param headers The Map to use to set header parameters. 144 * @see #setParameter(String, Object) 145 */ 146 public void setParameters(Map<String, Object> headers) { 147 for (String key : headers.keySet()) { 148 setParameter(key, headers.get(key)); 149 } 150 } 151 152 /** 153 * Gets a header parameter for the specified key. 154 * <p> 155 * If the key matches one of the reserved header parameter names, then the relevant <tt>get</tt> method is 156 * called to get that header parameter. 157 * 158 * @param key The header parameter key. 159 * @return The value stored against the header parameter key. 160 */ 161 public Object getParameter(String key) { 162 JwtHeaderKey headerKey = getHeaderKey(key.toUpperCase()); 163 164 Object value; 165 166 switch (headerKey) { 167 case TYP: { 168 value = getType(); 169 break; 170 } 171 case ALG: { 172 value = getAlgorithm(); 173 break; 174 } 175 default: { 176 value = get(key).getObject(); 177 } 178 } 179 180 return value; 181 } 182 183 /** 184 * Gets a header parameter for the specified key and then casts it to the specified type. 185 * 186 * @param key The header parameter key. 187 * @param clazz The class of the required type. 188 * @param <T> The required type for the header parameter value. 189 * @return The value stored against the header parameter key. 190 * @see #getParameter(String) 191 */ 192 public <T> T getParameter(String key, Class<T> clazz) { 193 return clazz.cast(getParameter(key)); 194 } 195 196 /** 197 * Returns this JwtHeader's parameters. 198 * 199 * @return {@code Map} of this JwtHeader's parameters. 200 */ 201 public Map<String, Object> getParameters() { 202 return getAll(); 203 } 204 205 /** 206 * Builds the JWT's header into a <code>String</code> representation of a JSON object. 207 * 208 * @return A JSON string. 209 */ 210 public String build() { 211 return toString(); 212 } 213 }