1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package fr.paris.lutece.util.jwt.service;
35
36 import io.jsonwebtoken.Claims;
37 import io.jsonwebtoken.JwtBuilder;
38 import io.jsonwebtoken.JwtException;
39 import io.jsonwebtoken.Jwts;
40 import io.jsonwebtoken.SignatureAlgorithm;
41 import java.io.UnsupportedEncodingException;
42 import java.security.Key;
43 import java.time.Instant;
44 import java.util.Date;
45 import java.util.Enumeration;
46 import java.util.Map;
47 import java.util.Map.Entry;
48 import javax.crypto.spec.SecretKeySpec;
49 import javax.servlet.http.HttpServletRequest;
50 import org.apache.logging.log4j.LogManager;
51 import org.apache.logging.log4j.Logger;
52
53
54
55
56
57 public class JWTUtil
58 {
59 protected static final Logger LOGGER = LogManager.getLogger( "lutece.security.jwt" );
60
61
62
63
64
65
66
67
68 public static boolean containsValidUnsafeJWT( HttpServletRequest request, String strHeaderName )
69 {
70 String strBase64JWT = request.getHeader( strHeaderName );
71
72
73 if ( strBase64JWT == null )
74 {
75 strBase64JWT = getAuthozirationBearerValue( request );
76 }
77
78 if ( strBase64JWT != null )
79 {
80 strBase64JWT = removeSignature( strBase64JWT );
81 try
82 {
83 Jwts.parser( ).parseClaimsJwt( strBase64JWT );
84 return true;
85 }
86 catch( JwtException e )
87 {
88 LOGGER.error( "Provided request doesn't contains any JWT in HTTP headers ", e );
89 }
90 }
91 return false;
92 }
93
94
95
96
97
98
99
100
101
102 public static boolean checkPayloadValues( HttpServletRequest request, String strHeaderName, Map<String, String> claimsToCheck )
103 {
104 String strBase64JWT = request.getHeader( strHeaderName );
105
106
107 if ( strBase64JWT == null )
108 {
109 strBase64JWT = getAuthozirationBearerValue( request );
110 }
111
112 if ( strBase64JWT != null )
113 {
114 strBase64JWT = removeSignature( strBase64JWT );
115 try
116 {
117 Claims claims = Jwts.parser( ).parseClaimsJwt( strBase64JWT ).getBody( );
118
119 for ( Entry<String, String> entry : claimsToCheck.entrySet( ) )
120 {
121 if ( !claims.get( entry.getKey( ), String.class ).equals( entry.getValue( ) ) )
122 {
123 return false;
124 }
125 }
126 }
127 catch( Exception e )
128 {
129 LOGGER.error( "Unable to check JWT payload for checking claims", e );
130 return false;
131 }
132 }
133 return true;
134 }
135
136
137
138
139
140
141
142
143
144 public static String getPayloadValue( HttpServletRequest request, String strHeaderName, String strClaimName )
145 {
146 String strBase64JWT = request.getHeader( strHeaderName );
147
148
149 if ( strBase64JWT == null )
150 {
151 strBase64JWT = getAuthozirationBearerValue( request );
152 }
153
154 getPayloadValue( strBase64JWT, strClaimName );
155 return null;
156 }
157
158
159
160
161
162
163
164
165 public static String getPayloadValue( String strBase64JWT, String strClaimName )
166 {
167 if ( strBase64JWT != null && !strBase64JWT.isEmpty( ) )
168 {
169 strBase64JWT = removeSignature( strBase64JWT );
170 try
171 {
172 Claims claims = Jwts.parser( ).parseClaimsJwt( strBase64JWT ).getBody( );
173
174 return (String) claims.get( strClaimName );
175 }
176 catch( Exception e )
177 {
178 LOGGER.error( "Unable to get JWT Payload value", e );
179 }
180 }
181 return null;
182 }
183
184
185
186
187
188
189
190
191
192
193
194
195 public static boolean checkSignature( HttpServletRequest request, String strHeaderName, Key key )
196 {
197 String strBase64JWT = request.getHeader( strHeaderName );
198
199
200 if ( strBase64JWT == null )
201 {
202 strBase64JWT = getAuthozirationBearerValue( request );
203 }
204
205 return checkSignature( strBase64JWT, key );
206 }
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222 public static String buildBase64JWT( Map<String,String> mapClaims, Date expirationDate, String strAlgo, Key key )
223 {
224 JwtBuilder builder = Jwts.builder();
225
226 builder.setIssuedAt( Date.from(Instant.now( ) ) );
227
228
229 for ( Entry<String,String> entry : mapClaims.entrySet( ) )
230 {
231 builder.claim( entry.getKey( ), entry.getValue( ) );
232 }
233
234 if ( expirationDate != null )
235 {
236 builder.setExpiration( expirationDate );
237 }
238
239
240 if ( key != null )
241 {
242 SignatureAlgorithm algo = SignatureAlgorithm.valueOf( strAlgo );
243 if ( algo != null )
244 {
245 builder.signWith( algo, key );
246 }
247 }
248
249 return builder.compact();
250 }
251
252
253
254
255
256
257
258
259
260 public static Key getKey( String strSecretKey, String strAlgoName )
261 {
262 try
263 {
264 Key key = new SecretKeySpec( strSecretKey.getBytes( "UTF-8"), strAlgoName );
265 return key;
266 }
267 catch ( UnsupportedEncodingException e )
268 {
269 }
270 return null;
271 }
272
273
274
275
276
277
278
279
280
281
282
283 private static String getAuthozirationBearerValue( HttpServletRequest request )
284 {
285 Enumeration<String> headers = request.getHeaders( "Authorization" );
286 while ( headers.hasMoreElements( ) )
287 {
288 String value = headers.nextElement( );
289 if ( value.toLowerCase( ).startsWith( "bearer" ) )
290 {
291 return value.substring( "bearer".length( ) ).trim( );
292 }
293 }
294 return null;
295 }
296
297
298
299
300
301
302
303
304 public static boolean checkSignature( String strBase64JWT, Key key )
305 {
306 try
307 {
308 Jwts.parser( ).setSigningKey( key ).parseClaimsJws( strBase64JWT );
309 }
310
311 catch( JwtException e )
312 {
313 return false;
314 }
315 return true;
316 }
317
318
319
320
321
322
323
324 private static String removeSignature( String strBase64JWT )
325 {
326 int i = strBase64JWT.lastIndexOf( "." );
327 return strBase64JWT.substring( 0, i + 1 );
328 }
329 }