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.plugins.oauth2.business;
35
36 import java.net.URI;
37 import java.net.URISyntaxException;
38 import java.util.Arrays;
39 import java.util.Objects;
40
41 import com.fasterxml.jackson.annotation.JsonProperty;
42
43 import fr.paris.lutece.portal.service.util.AppException;
44
45
46
47
48
49
50
51
52 public class OpenIDConfiguration
53 {
54 private String _strIssuer;
55 private String _strAuthorizationEndpoint;
56 private String _strTokenEndpoint;
57 private String _strUserinfoEndpoint;
58 private String _strJwksURI;
59 private String _strRegistrationEndpoint;
60 private String [ ] _scopesSupported;
61 private String [ ] _responseTypesSupported;
62 private String [ ] _responseModesSupported;
63 private String [ ] _grantTypesSupported;
64 private String [ ] _acrValuesSupported;
65 private String [ ] _subjectTypesSupported;
66 private String [ ] _idTokenSigningAlgValuesSupported;
67 private String [ ] _idTokenEncryptionAlgValuesSupported;
68 private String [ ] _idTokenEncryptionEncValuesSupported;
69 private String [ ] _userinfoSigningAlgValuesSupported;
70 private String [ ] _userinfoEncryptionAlgValuesSupported;
71 private String [ ] _userinfoEncryptionEncValuesSupported;
72 private String [ ] _requestObjectSigningAlgValuesSupported;
73 private String [ ] _requestObjectEncryptionAlgValuesSupported;
74 private String [ ] _requestObjectEncryptionEncValuesSupported;
75 private String [ ] _tokenEndpointAuthMethodsSupported;
76 private String [ ] _tokenEndpointAuthSigningAlgValuesSupported;
77 private String [ ] _displayValuesSupported;
78 private String [ ] _claimTypesSupported;
79 private String [ ] _claimsSupported;
80 private String _serviceDocumentation;
81 private String [ ] _claimsLocalesSupported;
82 private String [ ] _uiLocalesSupported;
83 private boolean _claimsParameterSupported;
84 private boolean _requestParameterSupported;
85 private boolean _requestUIRParameterSupported = true;
86 private boolean _requireRequestUIRRegistration;
87 private String _opPolicyURI;
88 private String _opTOSURI;
89 private String _strEndSessionEndpoint;
90
91 public String getIssuer( )
92 {
93 return _strIssuer;
94 }
95
96 public void setIssuer( String strIssuer )
97 {
98 _strIssuer = strIssuer;
99 }
100
101 @JsonProperty( "authorization_endpoint" )
102 public String getAuthorizationEndpoint( )
103 {
104 return _strAuthorizationEndpoint;
105 }
106
107 @JsonProperty( "authorization_endpoint" )
108 public void getAuthorizationEndpoint( String strAuthorizationEndpoint )
109 {
110 _strAuthorizationEndpoint = strAuthorizationEndpoint;
111 }
112
113 public String getTokenEndpoint( )
114 {
115 return _strTokenEndpoint;
116 }
117
118 @JsonProperty( "token_endpoint" )
119 public void setTokenEndpoint( String strTokenEndpoint )
120 {
121 _strTokenEndpoint = strTokenEndpoint;
122 }
123
124 public String getUserinfoEndpoint( )
125 {
126 return _strUserinfoEndpoint;
127 }
128
129 @JsonProperty( "userinfo_endpoint" )
130 public void setUserinfoEndpoint( String strUserinfoEndpoint )
131 {
132 _strUserinfoEndpoint = strUserinfoEndpoint;
133 }
134
135 public String getJwksURI( )
136 {
137 return _strJwksURI;
138 }
139
140 @JsonProperty( "jwks_uri" )
141 public void setJwksUri( String strJwksURI )
142 {
143 _strJwksURI = strJwksURI;
144 }
145
146 public String getRegistrationEndpoint( )
147 {
148 return _strRegistrationEndpoint;
149 }
150
151 @JsonProperty( "registration_endpoint" )
152 public void setRegistrationEndpoint( String strRegistrationEndpoint )
153 {
154 _strRegistrationEndpoint = strRegistrationEndpoint;
155 }
156
157 public String [ ] getScopesSupported( )
158 {
159 return _scopesSupported;
160 }
161
162 @JsonProperty( "scopes_supported" )
163 public void setScopesSupported( String [ ] scopesSupported )
164 {
165 this._scopesSupported = scopesSupported;
166 }
167
168 public String [ ] getResponseTypesSupported( )
169 {
170 return _responseTypesSupported;
171 }
172
173 @JsonProperty( "response_types_supported" )
174 public void setResponseTypesSupported( String [ ] responseTypesSupported )
175 {
176 this._responseTypesSupported = responseTypesSupported;
177 }
178
179 public String [ ] getResponseModesSupported( )
180 {
181 return _responseModesSupported;
182 }
183
184 @JsonProperty( "response_modes_supported" )
185 public void setResponseModesSupported( String [ ] responseModesSupported )
186 {
187 this._responseModesSupported = responseModesSupported;
188 }
189
190 public String [ ] getGrantTypesSupported( )
191 {
192 return _grantTypesSupported;
193 }
194
195 @JsonProperty( "grant_types_supported" )
196 public void setGrantTypesSupported( String [ ] grantTypesSupported )
197 {
198 this._grantTypesSupported = grantTypesSupported;
199 }
200
201 public String [ ] getAcrValuesSupported( )
202 {
203 return _acrValuesSupported;
204 }
205
206 @JsonProperty( "acr_values_supported" )
207 public void setAcrValuesSupported( String [ ] acrValuesSupported )
208 {
209 this._acrValuesSupported = acrValuesSupported;
210 }
211
212 public String [ ] getSubjectTypesSupported( )
213 {
214 return _subjectTypesSupported;
215 }
216
217 @JsonProperty( "subject_types_supported" )
218 public void setSubjectTypesSupported( String [ ] subjectTypesSupported )
219 {
220 this._subjectTypesSupported = subjectTypesSupported;
221 }
222
223 public String [ ] getIDTokenSigningAlgValuesSupported( )
224 {
225 return _idTokenSigningAlgValuesSupported;
226 }
227
228 @JsonProperty( "id_token_signing_alg_values_supported" )
229 public void setIDTokenSigningAlgValuesSupported( String [ ] idTokenSigningAlgValuesSupported )
230 {
231 this._idTokenSigningAlgValuesSupported = idTokenSigningAlgValuesSupported;
232 }
233
234 public String [ ] getIDTokenEncryptionAlgValuesSupported( )
235 {
236 return _idTokenEncryptionAlgValuesSupported;
237 }
238
239 @JsonProperty( "id_token_encryption_alg_values_supported" )
240 public void setIDTokenEncryptionAlgValuesSupported( String [ ] idTokenEncryptionAlgValuesSupported )
241 {
242 this._idTokenEncryptionAlgValuesSupported = idTokenEncryptionAlgValuesSupported;
243 }
244
245 public String [ ] getIDTokenEncryptionEncValuesSupported( )
246 {
247 return _idTokenEncryptionEncValuesSupported;
248 }
249
250 @JsonProperty( "id_token_encryption_enc_values_supported" )
251 public void setIDTokenEncryptionEncValuesSupported( String [ ] _idTokenEncryptionEncValuesSupported )
252 {
253 this._idTokenEncryptionEncValuesSupported = _idTokenEncryptionEncValuesSupported;
254 }
255
256 public String [ ] getUserinfoSigningAlgValuesSupported( )
257 {
258 return _userinfoSigningAlgValuesSupported;
259 }
260
261 @JsonProperty( "userinfo_signing_alg_values_supported" )
262 public void setUserinfoSigningAlgValuesSupported( String [ ] userinfoSigningAlgValuesSupported )
263 {
264 this._userinfoSigningAlgValuesSupported = userinfoSigningAlgValuesSupported;
265 }
266
267 public String [ ] getUserinfoEncryptionAlgValuesSupported( )
268 {
269 return _userinfoEncryptionAlgValuesSupported;
270 }
271
272 @JsonProperty( "userinfo_encryption_alg_values_supported" )
273 public void setUserinfoEncryptionAlgValuesSupported( String [ ] userinfoEncryptionAlgValuesSupported )
274 {
275 this._userinfoEncryptionAlgValuesSupported = userinfoEncryptionAlgValuesSupported;
276 }
277
278 public String [ ] getUserinfoEncryptionEncValuesSupported( )
279 {
280 return _userinfoEncryptionEncValuesSupported;
281 }
282
283 @JsonProperty( "userinfo_encryption_enc_values_supported" )
284 public void setUserinfoEncryptionEncValuesSupported( String [ ] userinfoEncryptionEncValuesSupported )
285 {
286 this._userinfoEncryptionEncValuesSupported = userinfoEncryptionEncValuesSupported;
287 }
288
289 public String [ ] getRequestObjectSigningAlgValuesSupported( )
290 {
291 return _requestObjectSigningAlgValuesSupported;
292 }
293
294 @JsonProperty( "request_object_signing_alg_values_supported" )
295 public void setRequestObjectSigningAlgValuesSupported( String [ ] requestObjectSigningAlgValuesSupported )
296 {
297 this._requestObjectSigningAlgValuesSupported = requestObjectSigningAlgValuesSupported;
298 }
299
300 public String [ ] getRequestObjectEncryptionAlgValuesSupported( )
301 {
302 return _requestObjectEncryptionAlgValuesSupported;
303 }
304
305 @JsonProperty( "request_object_encryption_alg_values_supported" )
306 public void setRequestObjectEncryptionAlgValuesSupported( String [ ] requestObjectEncryptionAlgValuesSupported )
307 {
308 this._requestObjectEncryptionAlgValuesSupported = requestObjectEncryptionAlgValuesSupported;
309 }
310
311 public String [ ] getRequestObjectEncryptionEncValuesSupported( )
312 {
313 return _requestObjectEncryptionEncValuesSupported;
314 }
315
316 @JsonProperty( "request_object_encryption_enc_values_supported" )
317 public void setRequestObjectEncryptionEncValuesSupported( String [ ] requestObjectEncryptionEncValuesSupported )
318 {
319 this._requestObjectEncryptionEncValuesSupported = requestObjectEncryptionEncValuesSupported;
320 }
321
322 public String [ ] getTokenEndpointAuthMethodsSupported( )
323 {
324 return _tokenEndpointAuthMethodsSupported;
325 }
326
327 @JsonProperty( "token_endpoint_auth_methods_supported" )
328 public void setTokenEndpointAuthMethodsSupported( String [ ] tokenEndpointAuthMethodsSupported )
329 {
330 this._tokenEndpointAuthMethodsSupported = tokenEndpointAuthMethodsSupported;
331 }
332
333 public String [ ] getTokenEndpointAuthSigningAlgValuesSupported( )
334 {
335 return _tokenEndpointAuthSigningAlgValuesSupported;
336 }
337
338 @JsonProperty( "token_endpoint_auth_signing_alg_values_supported" )
339 public void setTokenEndpointAuthSigningAlgValuesSupported( String [ ] tokenEndpointAuthSigningAlgValuesSupported )
340 {
341 this._tokenEndpointAuthSigningAlgValuesSupported = tokenEndpointAuthSigningAlgValuesSupported;
342 }
343
344 public String [ ] getDisplayValuesSupported( )
345 {
346 return _displayValuesSupported;
347 }
348
349 @JsonProperty( "display_values_supported" )
350 public void setDisplayValuesSupported( String [ ] displayValuesSupported )
351 {
352 this._displayValuesSupported = displayValuesSupported;
353 }
354
355 public String [ ] getClaimTypesSupported( )
356 {
357 return _claimTypesSupported;
358 }
359
360 @JsonProperty( "claim_types_supported" )
361 public void setClaimTypesSupported( String [ ] claimTypesSupported )
362 {
363 this._claimTypesSupported = claimTypesSupported;
364 }
365
366 public String [ ] getClaimsSupported( )
367 {
368 return _claimsSupported;
369 }
370
371 @JsonProperty( "claims_supported" )
372 public void setClaimsSupported( String [ ] claimsSupported )
373 {
374 this._claimsSupported = claimsSupported;
375 }
376
377 public String getServiceDocumentation( )
378 {
379 return _serviceDocumentation;
380 }
381
382 @JsonProperty( "service_documentation" )
383 public void setServiceDocumentation( String serviceDocumentation )
384 {
385 this._serviceDocumentation = serviceDocumentation;
386 }
387
388 public String [ ] getClaimsLocalesSupported( )
389 {
390 return _claimsLocalesSupported;
391 }
392
393 @JsonProperty( "claims_locales_supported" )
394 public void setClaimsLocalesSupported( String [ ] claimsLocalesSupported )
395 {
396 this._claimsLocalesSupported = claimsLocalesSupported;
397 }
398
399 public String [ ] getUILocalesSupported( )
400 {
401 return _uiLocalesSupported;
402 }
403
404 @JsonProperty( "ui_locales_supported" )
405 public void setUILocalesSupported( String [ ] uiLocalesSupported )
406 {
407 this._uiLocalesSupported = uiLocalesSupported;
408 }
409
410 public boolean isClaimsParameterSupported( )
411 {
412 return _claimsParameterSupported;
413 }
414
415 @JsonProperty( "claims_parameter_supported" )
416 public void setClaimsParameterSupported( boolean claimsParameterSupported )
417 {
418 this._claimsParameterSupported = claimsParameterSupported;
419 }
420
421 public boolean isRequestParameterSupported( )
422 {
423 return _requestParameterSupported;
424 }
425
426 @JsonProperty( "request_parameter_supported" )
427 public void setRequestParameterSupported( boolean requestParameterSupported )
428 {
429 this._requestParameterSupported = requestParameterSupported;
430 }
431
432 public boolean isRequestUIRParameterSupported( )
433 {
434 return _requestUIRParameterSupported;
435 }
436
437 @JsonProperty( "request_uri_parameter_supported" )
438 public void setRequestUIRParameterSupported( boolean requestUIRParameterSupported )
439 {
440 this._requestUIRParameterSupported = requestUIRParameterSupported;
441 }
442
443 public boolean isRequireRequestUIRRegistration( )
444 {
445 return _requireRequestUIRRegistration;
446 }
447
448 @JsonProperty( "require_request_uri_registration" )
449 public void setRequireRequestUIRRegistration( boolean requireRequestUIRRegistration )
450 {
451 this._requireRequestUIRRegistration = requireRequestUIRRegistration;
452 }
453
454 public String getOpPolicyURI( )
455 {
456 return _opPolicyURI;
457 }
458
459 @JsonProperty( "op_policy_uri" )
460 public void setOpPolicyURI( String opPolicyURI )
461 {
462 this._opPolicyURI = opPolicyURI;
463 }
464
465 public String getOpTOSURI( )
466 {
467 return _opTOSURI;
468 }
469
470 @JsonProperty( "op_tos_uri" )
471 public void setOpTOSURI( String opTOSURI )
472 {
473 this._opTOSURI = opTOSURI;
474 }
475
476 public String getEndSessionEndpoint( )
477 {
478 return _strEndSessionEndpoint;
479 }
480
481 @JsonProperty( "end_session_endpoint" )
482 public void setEndSessionEndpoint( String strEndSessionEndpoint )
483 {
484 this._strEndSessionEndpoint = strEndSessionEndpoint;
485 }
486
487
488
489
490
491
492
493
494
495
496
497 public void validate( String strExpectedIssuer )
498 {
499 validateIssuer( strExpectedIssuer );
500 validateAuthorizationEndpoint( );
501 validateTokenEndpoint( );
502 validateUserinfoEndpoint( );
503 validateJwksURI( );
504 validateRegistrationEndpoint( );
505 validateScopesSupported( );
506 validateResponseTypeSupported( );
507 validateSubjectTypesSupported( );
508 validateIDTokenSigningAlgValuesSupported( );
509 validateTokenEndpointAuthSigningAlgValuesSupported( );
510 validateEndSessionEndpoint( );
511 }
512
513 private void validateIssuer( String strExpectedIssuer )
514 {
515 Objects.requireNonNull( _strIssuer, "issuer is required" );
516 validateURI( _strIssuer, "issuer", false, false );
517 if ( !_strIssuer.equals( strExpectedIssuer ) )
518 {
519 throw new AppException( "Expected issuer " + strExpectedIssuer + ", but got " + _strIssuer );
520 }
521 }
522
523 private void validateAuthorizationEndpoint( )
524 {
525 Objects.requireNonNull( _strAuthorizationEndpoint, "Authorization endpoint is required" );
526 validateURI( _strAuthorizationEndpoint, "Authorization endpoint" );
527 }
528
529 private void validateTokenEndpoint( )
530 {
531 if ( _strTokenEndpoint == null )
532 {
533
534 return;
535 }
536 validateURI( _strTokenEndpoint, "Token endpoint" );
537 }
538
539 private void validateUserinfoEndpoint( )
540 {
541 if ( _strUserinfoEndpoint == null )
542 {
543 return;
544 }
545 validateURI( _strUserinfoEndpoint, "Userinfo endpoint" );
546 }
547
548 private void validateJwksURI( )
549 {
550 Objects.requireNonNull( _strJwksURI, "JWKS URI is required" );
551 validateURI( _strJwksURI, "JWKS URI" );
552 }
553
554 private void validateRegistrationEndpoint( )
555 {
556 if ( _strRegistrationEndpoint == null )
557 {
558 return;
559 }
560 validateURI( _strRegistrationEndpoint, "Registration endpoint" );
561 }
562
563 private void validateScopesSupported( )
564 {
565
566
567 }
568
569 private void validateResponseTypeSupported( )
570 {
571 Objects.requireNonNull( _responseTypesSupported, "Response types supported is required" );
572 for ( String type : _responseTypesSupported )
573 {
574 Objects.requireNonNull( type, "response type must not be null" );
575 }
576 }
577
578 private void validateSubjectTypesSupported( )
579 {
580 Objects.requireNonNull( _subjectTypesSupported, "Subject types supported is required" );
581 for ( String type : _subjectTypesSupported )
582 {
583 Objects.requireNonNull( type, "subject type must not be null" );
584 }
585 }
586
587 private void validateTokenEndpointAuthSigningAlgValuesSupported( )
588 {
589 if ( _tokenEndpointAuthSigningAlgValuesSupported == null )
590 {
591 return;
592 }
593 if ( Arrays.stream( _tokenEndpointAuthSigningAlgValuesSupported ).anyMatch( alg -> "none".equals( alg ) ) )
594 {
595 throw new AppException( "The algorithm none MUST NOT be used for the token endpoint auth signing alg values supported" );
596 }
597 }
598
599 private void validateEndSessionEndpoint( )
600 {
601 if ( _strEndSessionEndpoint == null )
602 {
603 return;
604 }
605 validateURI( _strEndSessionEndpoint, "end session endpoint" );
606 }
607
608 private void validateIDTokenSigningAlgValuesSupported( )
609 {
610 Objects.requireNonNull( _idTokenSigningAlgValuesSupported, "ID Token signing alg values supported is required" );
611 if ( Arrays.stream( _idTokenSigningAlgValuesSupported ).noneMatch( alg -> "RS256".equals( alg ) ) )
612 {
613 throw new AppException( "The algorithm RS256 MUST be included in ID Token signing alg values supported" );
614 }
615 }
616
617 private void validateURI( String strURI, String strFieldName )
618 {
619 validateURI( strURI, strFieldName, true, true );
620 }
621
622 private void validateURI( String strURI, String strFieldName, boolean queryAllowed, boolean fragmentAllowed )
623 {
624 try
625 {
626 URI theURI = new URI( strURI );
627 if ( !theURI.getScheme( ).equals( "https" ) )
628 {
629 throw new AppException( strFieldName + " must be a URL using the https scheme" );
630 }
631 if ( !queryAllowed && theURI.getQuery( ) != null )
632 {
633 throw new AppException( strFieldName + " must be a URL with no query component" );
634 }
635 if ( !fragmentAllowed && theURI.getFragment( ) != null )
636 {
637 throw new AppException( strFieldName + " must be a URL with no fragment component" );
638 }
639 }
640 catch( URISyntaxException e )
641 {
642 throw new AppException( "Unable to validate URI <" + strURI + "> for field " + strFieldName + ": " + e.getMessage( ), e );
643 }
644 }
645 }