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 }