View Javadoc
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 }