001package com.nimbusds.openid.connect.sdk.op;
002
003
004import java.net.URI;
005import java.net.URISyntaxException;
006import java.util.*;
007
008import net.minidev.json.JSONObject;
009
010import com.nimbusds.jose.Algorithm;
011import com.nimbusds.jose.EncryptionMethod;
012import com.nimbusds.jose.JWEAlgorithm;
013import com.nimbusds.jose.JWSAlgorithm;
014
015import com.nimbusds.langtag.LangTag;
016import com.nimbusds.langtag.LangTagException;
017
018import com.nimbusds.oauth2.sdk.*;
019import com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod;
020import com.nimbusds.oauth2.sdk.id.Issuer;
021import com.nimbusds.oauth2.sdk.util.JSONObjectUtils;
022
023import com.nimbusds.openid.connect.sdk.Display;
024import com.nimbusds.openid.connect.sdk.SubjectType;
025import com.nimbusds.openid.connect.sdk.claims.ACR;
026import com.nimbusds.openid.connect.sdk.claims.ClaimType;
027
028
029/**
030 * OpenID Connect provider metadata.
031 *
032 * <p>Related specifications:
033 *
034 * <ul>
035 *     <li>OpenID Connect Discovery 1.0, section 3.
036 * </ul>
037 */
038public class OIDCProviderMetadata {
039
040
041        /**
042         * The registered parameter names.
043         */
044        private static final Set<String> REGISTERED_PARAMETER_NAMES;
045
046
047        /**
048         * Initialises the registered parameter name set.
049         */
050        static {
051                Set<String> p = new HashSet<>();
052
053                p.add("issuer");
054                p.add("authorization_endpoint");
055                p.add("token_endpoint");
056                p.add("userinfo_endpoint");
057                p.add("registration_endpoint");
058                p.add("check_session_iframe");
059                p.add("end_session_endpoint");
060                p.add("jwks_uri");
061                p.add("scopes_supported");
062                p.add("response_types_supported");
063                p.add("response_modes_supported");
064                p.add("grant_types_supported");
065                p.add("acr_values_supported");
066                p.add("subject_types_supported");
067                p.add("token_endpoint_auth_methods_supported");
068                p.add("token_endpoint_auth_signing_alg_values_supported");
069                p.add("request_object_signing_alg_values_supported");
070                p.add("request_object_encryption_alg_values_supported");
071                p.add("request_object_encryption_enc_values_supported");
072                p.add("id_token_signing_alg_values_supported");
073                p.add("id_token_encryption_alg_values_supported");
074                p.add("id_token_encryption_enc_values_supported");
075                p.add("userinfo_signing_alg_values_supported");
076                p.add("userinfo_encryption_alg_values_supported");
077                p.add("userinfo_encryption_enc_values_supported");
078                p.add("display_values_supported");
079                p.add("claim_types_supported");
080                p.add("claims_supported");
081                p.add("claims_locales_supported");
082                p.add("ui_locales_supported");
083                p.add("service_documentation");
084                p.add("op_policy_uri");
085                p.add("op_tos_uri");
086                p.add("claims_parameter_supported");
087                p.add("request_parameter_supported");
088                p.add("request_uri_parameter_supported");
089                p.add("require_request_uri_registration");
090
091                REGISTERED_PARAMETER_NAMES = Collections.unmodifiableSet(p);
092        }
093
094
095        /**
096         * The issuer.
097         */
098        private final Issuer issuer;
099
100
101        /**
102         * The authorisation endpoint.
103         */
104        private URI authzEndpoint;
105
106
107        /**
108         * The token endpoint.
109         */
110        private URI tokenEndpoint;
111
112
113        /**
114         * The UserInfo endpoint.
115         */
116        private URI userInfoEndpoint;
117
118
119        /**
120         * The registration endpoint.
121         */
122        private URI regEndpoint;
123        
124        
125        /**
126         * The cross-origin check session iframe.
127         */
128        private URI checkSessionIframe;
129        
130        
131        /**
132         * The logout endpoint.
133         */
134        private URI endSessionEndpoint;
135
136
137        /**
138         * The JWK set URI.
139         */
140        private final URI jwkSetURI;
141
142
143        /**
144         * The supported scope values.
145         */
146        private Scope scope;
147
148
149        /**
150         * The supported response types.
151         */
152        private List<ResponseType> rts;
153
154
155        /**
156         * The supported response modes.
157         */
158        private List<ResponseMode> rms;
159        
160        
161        /**
162         * The supported grant types.
163         */
164        private List<GrantType> gts;
165
166
167        /**
168         * The supported ACRs.
169         */
170        private List<ACR> acrValues;
171
172
173        /**
174         * The supported subject types.
175         */
176        private final List<SubjectType> subjectTypes;
177
178
179        /**
180         * The supported token endpoint authentication methods.
181         */
182        private List<ClientAuthenticationMethod> tokenEndpointAuthMethods;
183
184
185        /**
186         * The supported JWS algorithms for the {@code private_key_jwt} and 
187         * {@code client_secret_jwt} token endpoint authentication methods.
188         */
189        private List<JWSAlgorithm> tokenEndpointJWSAlgs;
190
191
192        /**
193         * The supported JWS algorithms for OpenID Connect request objects.
194         */
195        private List<JWSAlgorithm> requestObjectJWSAlgs;
196
197
198        /**
199         * The supported JWE algorithms for OpenID Connect request objects.
200         */
201        private List<JWEAlgorithm> requestObjectJWEAlgs;
202
203
204        /**
205         * The supported encryption methods for OpenID Connect request objects.
206         */
207        private List<EncryptionMethod> requestObjectJWEEncs;
208
209
210        /**
211         * The supported ID token JWS algorithms.
212         */
213        private List<JWSAlgorithm> idTokenJWSAlgs;
214
215
216        /**
217         * The supported ID token JWE algorithms.
218         */
219        private List<JWEAlgorithm> idTokenJWEAlgs;
220
221
222        /**
223         * The supported ID token encryption methods.
224         */
225        private List<EncryptionMethod> idTokenJWEEncs;
226
227
228        /**
229         * The supported UserInfo JWS algorithms.
230         */
231        private List<JWSAlgorithm> userInfoJWSAlgs;
232
233
234        /**
235         * The supported UserInfo JWE algorithms.
236         */
237        private List<JWEAlgorithm> userInfoJWEAlgs;
238
239
240        /**
241         * The supported UserInfo encryption methods.
242         */
243        private List<EncryptionMethod> userInfoJWEEncs;
244
245
246        /**
247         * The supported displays.
248         */
249        private List<Display> displays;
250        
251        
252        /**
253         * The supported claim types.
254         */
255        private List<ClaimType> claimTypes;
256
257
258        /**
259         * The supported claims names.
260         */
261        private List<String> claims;
262        
263        
264        /**
265         * The supported claims locales.
266         */
267        private List<LangTag> claimsLocales;
268        
269        
270        /**
271         * The supported UI locales.
272         */
273        private List<LangTag> uiLocales;
274
275
276        /**
277         * The service documentation URI.
278         */
279        private URI serviceDocsURI;
280        
281        
282        /**
283         * The provider's policy regarding relying party use of data.
284         */
285        private URI policyURI;
286        
287        
288        /**
289         * The provider's terms of service.
290         */
291        private URI tosURI;
292        
293        
294        /**
295         * If {@code true} the {@code claims} parameter is supported, else not.
296         */
297        private boolean claimsParamSupported = false;
298        
299        
300        /**
301         * If {@code true} the {@code request} parameter is supported, else 
302         * not.
303         */
304        private boolean requestParamSupported = false;
305        
306        
307        /**
308         * If {@code true} the {@code request_uri} parameter is supported, else
309         * not.
310         */
311        private boolean requestURIParamSupported = true;
312        
313        
314        /**
315         * If {@code true} the {@code request_uri} parameters must be
316         * pre-registered with the provider, else not.
317         */
318        private boolean requireRequestURIReg = false;
319
320
321        /**
322         * Creates a new OpenID Connect provider metadata instance.
323         * 
324         * @param issuer       The issuer identifier. Must be an URI using the
325         *                     https scheme with no query or fragment 
326         *                     component. Must not be {@code null}.
327         * @param subjectTypes The supported subject types. At least one must
328         *                     be specified. Must not be {@code null}.
329         */
330        public OIDCProviderMetadata(final Issuer issuer,
331                                    final List<SubjectType> subjectTypes,
332                                    final URI jwkSetURI) {
333        
334                URI url;
335                
336                try {
337                        url = new URI(issuer.getValue());
338                        
339                } catch (URISyntaxException e) {
340                        
341                        throw new IllegalArgumentException("The issuer identifier must be a URI: " + e.getMessage(), e);
342                }
343                
344                if (url.getRawQuery() != null)
345                        throw new IllegalArgumentException("The issuer URI must be without a query component");
346                
347                if (url.getRawFragment() != null)
348                        throw new IllegalArgumentException("The issuer URI must be without a fragment component ");
349                
350                this.issuer = issuer;
351                
352                
353                if (subjectTypes.size() < 1)
354                        throw new IllegalArgumentException("At least one supported subject type must be specified");
355                
356                this.subjectTypes = subjectTypes;
357
358                if (jwkSetURI == null)
359                        throw new IllegalArgumentException("The public JWK set URI must not be null");
360
361                this.jwkSetURI = jwkSetURI;
362        }
363
364
365        /**
366         * Gets the registered OpenID Connect provider metadata parameter
367         * names.
368         *
369         * @return The registered OpenID Connect provider metadata parameter
370         *         names, as an unmodifiable set.
371         */
372        public static Set<String> getRegisteredParameterNames() {
373
374                return REGISTERED_PARAMETER_NAMES;
375        }
376
377
378        /**
379         * Gets the issuer identifier. Corresponds to the {@code issuer} 
380         * metadata field.
381         *
382         * @return The issuer identifier.
383         */
384        public Issuer getIssuer() {
385
386                return issuer;
387        }
388
389
390        /**
391         * Gets the authorisation endpoint URI. Corresponds the
392         * {@code authorization_endpoint} metadata field.
393         *
394         * @return The authorisation endpoint URI, {@code null} if not
395         *         specified.
396         */
397        public URI getAuthorizationEndpointURI() {
398
399                return authzEndpoint;
400        }
401
402
403        /**
404         * Sets the authorisation endpoint URI. Corresponds the
405         * {@code authorization_endpoint} metadata field.
406         *
407         * @param authzEndpoint The authorisation endpoint URI, {@code null} if
408         *                      not specified.
409         */
410        public void setAuthorizationEndpointURI(final URI authzEndpoint) {
411
412                this.authzEndpoint = authzEndpoint;
413        }
414
415
416        /**
417         * Gets the token endpoint URI. Corresponds the {@code token_endpoint}
418         * metadata field.
419         *
420         * @return The token endpoint URI, {@code null} if not specified.
421         */
422        public URI getTokenEndpointURI() {
423
424                return tokenEndpoint;
425        }
426
427
428        /**
429         * Sts the token endpoint URI. Corresponds the {@code token_endpoint}
430         * metadata field.
431         *
432         * @param tokenEndpoint The token endpoint URI, {@code null} if not
433         *                      specified.
434         */
435        public void setTokenEndpointURI(final URI tokenEndpoint) {
436
437                this.tokenEndpoint = tokenEndpoint;
438        }
439
440
441        /**
442         * Gets the UserInfo endpoint URI. Corresponds the
443         * {@code userinfo_endpoint} metadata field.
444         *
445         * @return The UserInfo endpoint URI, {@code null} if not specified.
446         */
447        public URI getUserInfoEndpointURI() {
448
449                return userInfoEndpoint;
450        }
451
452
453        /**
454         * Sets the UserInfo endpoint URI. Corresponds the
455         * {@code userinfo_endpoint} metadata field.
456         *
457         * @param userInfoEndpoint The UserInfo endpoint URI, {@code null} if
458         *                         not specified.
459         */
460        public void setUserInfoEndpointURI(final URI userInfoEndpoint) {
461
462                this.userInfoEndpoint = userInfoEndpoint;
463        }
464
465
466        /**
467         * Gets the client registration endpoint URI. Corresponds to the
468         * {@code registration_endpoint} metadata field.
469         *
470         * @return The client registration endpoint URI, {@code null} if not
471         *         specified.
472         */
473        public URI getRegistrationEndpointURI() {
474
475                return regEndpoint;
476        }
477
478
479        /**
480         * Sets the client registration endpoint URI. Corresponds to the
481         * {@code registration_endpoint} metadata field.
482         *
483         * @param regEndpoint The client registration endpoint URI,
484         *                    {@code null} if not specified.
485         */
486        public void setRegistrationEndpointURI(final URI regEndpoint) {
487
488                this.regEndpoint = regEndpoint;
489        }
490        
491        
492        /**
493         * Gets the cross-origin check session iframe URI. Corresponds to the
494         * {@code check_session_iframe} metadata field.
495         * 
496         * @return The check session iframe URI, {@code null} if not specified.
497         */
498        public URI getCheckSessionIframeURI() {
499                
500                return checkSessionIframe;
501        }
502
503
504        /**
505         * Sets the cross-origin check session iframe URI. Corresponds to the
506         * {@code check_session_iframe} metadata field.
507         *
508         * @param checkSessionIframe The check session iframe URI, {@code null}
509         *                           if not specified.
510         */
511        public void setCheckSessionIframeURI(final URI checkSessionIframe) {
512
513                this.checkSessionIframe = checkSessionIframe;
514        }
515        
516        
517        /**
518         * Gets the logout endpoint URI. Corresponds to the
519         * {@code end_session_endpoint} metadata field.
520         * 
521         * @return The logoout endpoint URI, {@code null} if not specified.
522         */
523        public URI getEndSessionEndpointURI() {
524                
525                return endSessionEndpoint;
526        }
527
528
529        /**
530         * Sets the logout endpoint URI. Corresponds to the
531         * {@code end_session_endpoint} metadata field.
532         *
533         * @param endSessionEndpoint The logoout endpoint URI, {@code null} if
534         *                           not specified.
535         */
536        public void setEndSessionEndpointURI(final URI endSessionEndpoint) {
537
538                this.endSessionEndpoint = endSessionEndpoint;
539        }
540
541
542        /**
543         * Gets the JSON Web Key (JWK) set URI. Corresponds to the
544         * {@code jwks_uri} metadata field.
545         *
546         * @return The JWK set URI.
547         */
548        public URI getJWKSetURI() {
549
550                return jwkSetURI;
551        }
552
553
554        /**
555         * Gets the supported scope values. Corresponds to the
556         * {@code scopes_supported} metadata field.
557         *
558         * @return The supported scope values, {@code null} if not specified.
559         */
560        public Scope getScopes() {
561
562                return scope;
563        }
564
565
566        /**
567         * Sets the supported scope values. Corresponds to the
568         * {@code scopes_supported} metadata field.
569         *
570         * @param scope The supported scope values, {@code null} if not
571         *              specified.
572         */
573        public void setScopes(final Scope scope) {
574
575                this.scope = scope;
576        }
577
578
579        /**
580         * Gets the supported response type values. Corresponds to the
581         * {@code response_types_supported} metadata field.
582         *
583         * @return The supported response type values, {@code null} if not 
584         *         specified.
585         */
586        public List<ResponseType> getResponseTypes() {
587
588                return rts;
589        }
590
591
592        /**
593         * Sets the supported response type values. Corresponds to the
594         * {@code response_types_supported} metadata field.
595         *
596         * @param rts The supported response type values, {@code null} if not
597         *            specified.
598         */
599        public void setResponseTypes(final List<ResponseType> rts) {
600
601                this.rts = rts;
602        }
603
604
605        /**
606         * Gets the supported response mode values. Corresponds to the
607         * {@code response_modes_supported}.
608         *
609         * @return The supported response mode values, {@code null} if not
610         *         specified.
611         */
612        public List<ResponseMode> getResponseModes() {
613
614                return rms;
615        }
616
617
618        /**
619         * Sets the supported response mode values. Corresponds to the
620         * {@code response_modes_supported}.
621         *
622         * @param rms The supported response mode values, {@code null} if not
623         *            specified.
624         */
625        public void setResponseModes(final List<ResponseMode> rms) {
626
627                this.rms = rms;
628        }
629        
630        
631        /**
632         * Gets the supported OAuth 2.0 grant types. Corresponds to the
633         * {@code grant_types_supported} metadata field.
634         * 
635         * @return The supported grant types, {@code null} if not specified.
636         */
637        public List<GrantType> getGrantTypes() {
638                
639                return gts;
640        }
641
642
643        /**
644         * Sets the supported OAuth 2.0 grant types. Corresponds to the
645         * {@code grant_types_supported} metadata field.
646         *
647         * @param gts The supported grant types, {@code null} if not specified.
648         */
649        public void setGrantTypes(final List<GrantType> gts) {
650
651                this.gts = gts;
652        }
653
654
655        /**
656         * Gets the supported Authentication Context Class References (ACRs).
657         * Corresponds to the {@code acr_values_supported} metadata field.
658         *
659         * @return The supported ACRs, {@code null} if not specified.
660         */
661        public List<ACR> getACRs() {
662
663                return acrValues;
664        }
665
666
667        /**
668         * Sets the supported Authentication Context Class References (ACRs).
669         * Corresponds to the {@code acr_values_supported} metadata field.
670         *
671         * @param acrValues The supported ACRs, {@code null} if not specified.
672         */
673        public void setACRs(final List<ACR> acrValues) {
674
675                this.acrValues = acrValues;
676        }
677
678
679        /**
680         * Gets the supported subject types. Corresponds to the
681         * {@code subject_types_supported} metadata field.
682         *
683         * @return The supported subject types.
684         */
685        public List<SubjectType> getSubjectTypes() {
686
687                return subjectTypes;
688        }
689
690
691        /**
692         * Gets the supported token endpoint authentication methods. 
693         * Corresponds to the {@code token_endpoint_auth_methods_supported} 
694         * metadata field.
695         *
696         * @return The supported token endpoint authentication methods, 
697         *         {@code null} if not specified.
698         */
699        public List<ClientAuthenticationMethod> getTokenEndpointAuthMethods() {
700
701                return tokenEndpointAuthMethods;
702        }
703
704
705        /**
706         * Sets the supported token endpoint authentication methods.
707         * Corresponds to the {@code token_endpoint_auth_methods_supported}
708         * metadata field.
709         *
710         * @param tokenEndpointAuthMethods The supported token endpoint
711         *                                 authentication methods, {@code null}
712         *                                 if not specified.
713         */
714        public void setTokenEndpointAuthMethods(final List<ClientAuthenticationMethod> tokenEndpointAuthMethods) {
715
716                this.tokenEndpointAuthMethods = tokenEndpointAuthMethods;
717        }
718
719
720        /**
721         * Gets the supported JWS algorithms for the {@code private_key_jwt}
722         * and {@code client_secret_jwt} token endpoint authentication methods.
723         * Corresponds to the 
724         * {@code token_endpoint_auth_signing_alg_values_supported} metadata 
725         * field.
726         *
727         * @return The supported JWS algorithms, {@code null} if not specified.
728         */
729        public List<JWSAlgorithm> getTokenEndpointJWSAlgs() {
730
731                return tokenEndpointJWSAlgs;
732        }
733
734
735        /**
736         * Sets the supported JWS algorithms for the {@code private_key_jwt}
737         * and {@code client_secret_jwt} token endpoint authentication methods.
738         * Corresponds to the
739         * {@code token_endpoint_auth_signing_alg_values_supported} metadata
740         * field.
741         *
742         * @param tokenEndpointJWSAlgs The supported JWS algorithms,
743         *                             {@code null} if not specified. Must not
744         *                             contain the {@code none} algorithm.
745         */
746        public void setTokenEndpointJWSAlgs(final List<JWSAlgorithm> tokenEndpointJWSAlgs) {
747
748                if (tokenEndpointJWSAlgs != null && tokenEndpointJWSAlgs.contains(Algorithm.NONE))
749                        throw new IllegalArgumentException("The none algorithm is not accepted");
750
751                this.tokenEndpointJWSAlgs = tokenEndpointJWSAlgs;
752        }
753
754
755        /**
756         * Gets the supported JWS algorithms for OpenID Connect request 
757         * objects. Corresponds to the 
758         * {@code request_object_signing_alg_values_supported} metadata field.
759         *
760         * @return The supported JWS algorithms, {@code null} if not specified.
761         */
762        public List<JWSAlgorithm> getRequestObjectJWSAlgs() {
763
764                return requestObjectJWSAlgs;
765        }
766
767
768        /**
769         * Sets the supported JWS algorithms for OpenID Connect request
770         * objects. Corresponds to the
771         * {@code request_object_signing_alg_values_supported} metadata field.
772         *
773         * @param requestObjectJWSAlgs The supported JWS algorithms,
774         *                             {@code null} if not specified.
775         */
776        public void setRequestObjectJWSAlgs(final List<JWSAlgorithm> requestObjectJWSAlgs) {
777
778                this.requestObjectJWSAlgs = requestObjectJWSAlgs;
779        }
780
781
782        /**
783         * Gets the supported JWE algorithms for OpenID Connect request 
784         * objects. Corresponds to the
785         * {@code request_object_encryption_alg_values_supported} metadata 
786         * field.
787         *
788         * @return The supported JWE algorithms, {@code null} if not specified.
789         */
790        public List<JWEAlgorithm> getRequestObjectJWEAlgs() {
791
792                return requestObjectJWEAlgs;
793        }
794
795
796        /**
797         * Sets the supported JWE algorithms for OpenID Connect request
798         * objects. Corresponds to the
799         * {@code request_object_encryption_alg_values_supported} metadata
800         * field.
801         *
802         * @param requestObjectJWEAlgs The supported JWE algorithms,
803         *                            {@code null} if not specified.
804         */
805        public void setRequestObjectJWEAlgs(final List<JWEAlgorithm> requestObjectJWEAlgs) {
806
807                this.requestObjectJWEAlgs = requestObjectJWEAlgs;
808        }
809
810
811        /**
812         * Gets the supported encryption methods for OpenID Connect request 
813         * objects. Corresponds to the 
814         * {@code request_object_encryption_enc_values_supported} metadata 
815         * field.
816         *
817         * @return The supported encryption methods, {@code null} if not 
818         *         specified.
819         */
820        public List<EncryptionMethod> getRequestObjectJWEEncs() {
821
822                return requestObjectJWEEncs;
823        }
824
825
826        /**
827         * Sets the supported encryption methods for OpenID Connect request
828         * objects. Corresponds to the
829         * {@code request_object_encryption_enc_values_supported} metadata
830         * field.
831         *
832         * @param requestObjectJWEEncs The supported encryption methods,
833         *                             {@code null} if not specified.
834         */
835        public void setRequestObjectJWEEncs(final List<EncryptionMethod> requestObjectJWEEncs) {
836
837                this.requestObjectJWEEncs = requestObjectJWEEncs;
838        }
839
840
841        /**
842         * Gets the supported JWS algorithms for ID tokens. Corresponds to the 
843         * {@code id_token_signing_alg_values_supported} metadata field.
844         *
845         * @return The supported JWS algorithms, {@code null} if not specified.
846         */
847        public List<JWSAlgorithm> getIDTokenJWSAlgs() {
848
849                return idTokenJWSAlgs;
850        }
851
852
853        /**
854         * Sets the supported JWS algorithms for ID tokens. Corresponds to the
855         * {@code id_token_signing_alg_values_supported} metadata field.
856         *
857         * @param idTokenJWSAlgs The supported JWS algorithms, {@code null} if
858         *                       not specified.
859         */
860        public void setIDTokenJWSAlgs(final List<JWSAlgorithm> idTokenJWSAlgs) {
861
862                this.idTokenJWSAlgs = idTokenJWSAlgs;
863        }
864
865
866        /**
867         * Gets the supported JWE algorithms for ID tokens. Corresponds to the 
868         * {@code id_token_encryption_alg_values_supported} metadata field.
869         *
870         * @return The supported JWE algorithms, {@code null} if not specified.
871         */
872        public List<JWEAlgorithm> getIDTokenJWEAlgs() {
873
874                return idTokenJWEAlgs;
875        }
876
877
878        /**
879         * Sets the supported JWE algorithms for ID tokens. Corresponds to the
880         * {@code id_token_encryption_alg_values_supported} metadata field.
881         *
882         * @param idTokenJWEAlgs The supported JWE algorithms, {@code null} if
883         *                       not specified.
884         */
885        public void setIDTokenJWEAlgs(final List<JWEAlgorithm> idTokenJWEAlgs) {
886
887                this.idTokenJWEAlgs = idTokenJWEAlgs;
888        }
889
890
891        /**
892         * Gets the supported encryption methods for ID tokens. Corresponds to 
893         * the {@code id_token_encryption_enc_values_supported} metadata field.
894         *
895         * @return The supported encryption methods, {@code null} if not 
896         *         specified.
897         */
898        public List<EncryptionMethod> getIDTokenJWEEncs() {
899
900                return idTokenJWEEncs;
901        }
902
903
904        /**
905         * Sets the supported encryption methods for ID tokens. Corresponds to
906         * the {@code id_token_encryption_enc_values_supported} metadata field.
907         *
908         * @param idTokenJWEEncs The supported encryption methods, {@code null}
909         *                       if not specified.
910         */
911        public void setIDTokenJWEEncs(final List<EncryptionMethod> idTokenJWEEncs) {
912
913                this.idTokenJWEEncs = idTokenJWEEncs;
914        }
915
916
917        /**
918         * Gets the supported JWS algorithms for UserInfo JWTs. Corresponds to 
919         * the {@code userinfo_signing_alg_values_supported} metadata field.
920         *
921         * @return The supported JWS algorithms, {@code null} if not specified.
922         */
923        public List<JWSAlgorithm> getUserInfoJWSAlgs() {
924
925                return userInfoJWSAlgs;
926        }
927
928
929        /**
930         * Sets the supported JWS algorithms for UserInfo JWTs. Corresponds to
931         * the {@code userinfo_signing_alg_values_supported} metadata field.
932         *
933         * @param userInfoJWSAlgs The supported JWS algorithms, {@code null} if
934         *                        not specified.
935         */
936        public void setUserInfoJWSAlgs(final List<JWSAlgorithm> userInfoJWSAlgs) {
937
938                this.userInfoJWSAlgs = userInfoJWSAlgs;
939        }
940
941
942        /**
943         * Gets the supported JWE algorithms for UserInfo JWTs. Corresponds to 
944         * the {@code userinfo_encryption_alg_values_supported} metadata field.
945         *
946         * @return The supported JWE algorithms, {@code null} if not specified.
947         */
948        public List<JWEAlgorithm> getUserInfoJWEAlgs() {
949
950                return userInfoJWEAlgs;
951        }
952
953
954        /**
955         * Sets the supported JWE algorithms for UserInfo JWTs. Corresponds to
956         * the {@code userinfo_encryption_alg_values_supported} metadata field.
957         *
958         * @param userInfoJWEAlgs The supported JWE algorithms, {@code null} if
959         *                        not specified.
960         */
961        public void setUserInfoJWEAlgs(final List<JWEAlgorithm> userInfoJWEAlgs) {
962
963                this.userInfoJWEAlgs = userInfoJWEAlgs;
964        }
965
966
967        /**
968         * Gets the supported encryption methods for UserInfo JWTs. Corresponds 
969         * to the {@code userinfo_encryption_enc_values_supported} metadata 
970         * field.
971         *
972         * @return The supported encryption methods, {@code null} if not 
973         *         specified.
974         */
975        public List<EncryptionMethod> getUserInfoJWEEncs() {
976
977                return userInfoJWEEncs;
978        }
979
980
981        /**
982         * Sets the supported encryption methods for UserInfo JWTs. Corresponds
983         * to the {@code userinfo_encryption_enc_values_supported} metadata
984         * field.
985         *
986         * @param userInfoJWEEncs The supported encryption methods,
987         *                        {@code null} if not specified.
988         */
989        public void setUserInfoJWEEncs(final List<EncryptionMethod> userInfoJWEEncs) {
990
991                this.userInfoJWEEncs = userInfoJWEEncs;
992        }
993
994
995        /**
996         * Gets the supported displays. Corresponds to the 
997         * {@code display_values_supported} metadata field.
998         *
999         * @return The supported displays, {@code null} if not specified.
1000         */
1001        public List<Display> getDisplays() {
1002
1003                return displays;
1004        }
1005
1006
1007        /**
1008         * Sets the supported displays. Corresponds to the
1009         * {@code display_values_supported} metadata field.
1010         *
1011         * @param displays The supported displays, {@code null} if not
1012         *                 specified.
1013         */
1014        public void setDisplays(final List<Display> displays) {
1015
1016                this.displays = displays;
1017        }
1018        
1019        
1020        /**
1021         * Gets the supported claim types. Corresponds to the 
1022         * {@code claim_types_supported} metadata field.
1023         * 
1024         * @return The supported claim types, {@code null} if not specified.
1025         */
1026        public List<ClaimType> getClaimTypes() {
1027                
1028                return claimTypes;
1029        }
1030
1031
1032        /**
1033         * Sets the supported claim types. Corresponds to the
1034         * {@code claim_types_supported} metadata field.
1035         *
1036         * @param claimTypes The supported claim types, {@code null} if not
1037         *                   specified.
1038         */
1039        public void setClaimTypes(final List<ClaimType> claimTypes) {
1040
1041                this.claimTypes = claimTypes;
1042        }
1043
1044
1045        /**
1046         * Gets the supported claims names. Corresponds to the 
1047         * {@code claims_supported} metadata field.
1048         *
1049         * @return The supported claims names, {@code null} if not specified.
1050         */
1051        public List<String> getClaims() {
1052
1053                return claims;
1054        }
1055
1056
1057        /**
1058         * Sets the supported claims names. Corresponds to the
1059         * {@code claims_supported} metadata field.
1060         *
1061         * @param claims The supported claims names, {@code null} if not
1062         *               specified.
1063         */
1064        public void setClaims(final List<String> claims) {
1065
1066                this.claims = claims;
1067        }
1068        
1069        
1070        /**
1071         * Gets the supported claims locales. Corresponds to the
1072         * {@code claims_locales_supported} metadata field.
1073         * 
1074         * @return The supported claims locales, {@code null} if not specified.
1075         */
1076        public List<LangTag> getClaimsLocales() {
1077                
1078                return claimsLocales;
1079        }
1080
1081
1082        /**
1083         * Sets the supported claims locales. Corresponds to the
1084         * {@code claims_locales_supported} metadata field.
1085         *
1086         * @param claimsLocales The supported claims locales, {@code null} if
1087         *                      not specified.
1088         */
1089        public void setClaimLocales(final List<LangTag> claimsLocales) {
1090
1091                this.claimsLocales = claimsLocales;
1092        }
1093        
1094        
1095        /**
1096         * Gets the supported UI locales. Corresponds to the 
1097         * {@code ui_locales_supported} metadata field.
1098         * 
1099         * @return The supported UI locales, {@code null} if not specified.
1100         */
1101        public List<LangTag> getUILocales() {
1102                
1103                return uiLocales;
1104        }
1105
1106
1107        /**
1108         * Sets the supported UI locales. Corresponds to the
1109         * {@code ui_locales_supported} metadata field.
1110         *
1111         * @param uiLocales The supported UI locales, {@code null} if not
1112         *                  specified.
1113         */
1114        public void setUILocales(final List<LangTag> uiLocales) {
1115
1116                this.uiLocales = uiLocales;
1117        }
1118
1119
1120        /**
1121         * Gets the service documentation URI. Corresponds to the
1122         * {@code service_documentation} metadata field.
1123         *
1124         * @return The service documentation URI, {@code null} if not
1125         *         specified.
1126         */
1127        public URI getServiceDocsURI() {
1128
1129                return serviceDocsURI;
1130        }
1131
1132
1133        /**
1134         * Sets the service documentation URI. Corresponds to the
1135         * {@code service_documentation} metadata field.
1136         *
1137         * @param serviceDocsURI The service documentation URI, {@code null} if
1138         *                       not specified.
1139         */
1140        public void setServiceDocsURI(final URI serviceDocsURI) {
1141
1142                this.serviceDocsURI = serviceDocsURI;
1143        }
1144        
1145        
1146        /**
1147         * Gets the provider's policy regarding relying party use of data.
1148         * Corresponds to the {@code op_policy_uri} metadata field.
1149         * 
1150         * @return The policy URI, {@code null} if not specified.
1151         */
1152        public URI getPolicyURI() {
1153                
1154                return policyURI;
1155        }
1156
1157
1158        /**
1159         * Sets the provider's policy regarding relying party use of data.
1160         * Corresponds to the {@code op_policy_uri} metadata field.
1161         *
1162         * @param policyURI The policy URI, {@code null} if not specified.
1163         */
1164        public void setPolicyURI(final URI policyURI) {
1165
1166                this.policyURI = policyURI;
1167        }
1168        
1169        
1170        /**
1171         * Gets the provider's terms of service. Corresponds to the 
1172         * {@code op_tos_uri} metadata field.
1173         * 
1174         * @return The terms of service URI, {@code null} if not specified.
1175         */
1176        public URI getTermsOfServiceURI() {
1177                
1178                return tosURI;
1179        }
1180
1181
1182        /**
1183         * Sets the provider's terms of service. Corresponds to the
1184         * {@code op_tos_uri} metadata field.
1185         *
1186         * @param tosURI The terms of service URI, {@code null} if not
1187         *               specified.
1188         */
1189        public void setTermsOfServiceURI(final URI tosURI) {
1190
1191                this.tosURI = tosURI;
1192        }
1193        
1194        
1195        /**
1196         * Gets the support for the {@code claims} authorisation request
1197         * parameter. Corresponds to the {@code claims_parameter_supported} 
1198         * metadata field.
1199         * 
1200         * @return {@code true} if the {@code claim} parameter is supported,
1201         *         else {@code false}.
1202         */
1203        public boolean supportsClaimsParam() {
1204                
1205                return claimsParamSupported;
1206        }
1207
1208
1209        /**
1210         * Sets the support for the {@code claims} authorisation request
1211         * parameter. Corresponds to the {@code claims_parameter_supported}
1212         * metadata field.
1213         *
1214         * @param claimsParamSupported {@code true} if the {@code claim}
1215         *                             parameter is supported, else
1216         *                             {@code false}.
1217         */
1218        public void setSupportsClaimsParams(final boolean claimsParamSupported) {
1219
1220                this.claimsParamSupported = claimsParamSupported;
1221        }
1222        
1223        
1224        /**
1225         * Gets the support for the {@code request} authorisation request
1226         * parameter. Corresponds to the {@code request_parameter_supported}
1227         * metadata field.
1228         * 
1229         * @return {@code true} if the {@code reqeust} parameter is supported,
1230         *         else {@code false}.
1231         */
1232        public boolean supportsRequestParam() {
1233                
1234                return requestParamSupported;
1235        }
1236
1237
1238        /**
1239         * Sets the support for the {@code request} authorisation request
1240         * parameter. Corresponds to the {@code request_parameter_supported}
1241         * metadata field.
1242         *
1243         * @param requestParamSupported {@code true} if the {@code reqeust}
1244         *                              parameter is supported, else
1245         *                              {@code false}.
1246         */
1247        public void setSupportsRequestParam(final boolean requestParamSupported) {
1248
1249                this.requestParamSupported = requestParamSupported;
1250        }
1251        
1252        
1253        /**
1254         * Gets the support for the {@code request_uri} authorisation request
1255         * parameter. Corresponds the {@code request_uri_parameter_supported}
1256         * metadata field.
1257         * 
1258         * @return {@code true} if the {@code request_uri} parameter is
1259         *         supported, else {@code false}.
1260         */
1261        public boolean supportsRequestURIParam() {
1262                
1263                return requestURIParamSupported;
1264        }
1265
1266
1267        /**
1268         * Sets the support for the {@code request_uri} authorisation request
1269         * parameter. Corresponds the {@code request_uri_parameter_supported}
1270         * metadata field.
1271         *
1272         * @param requestURIParamSupported {@code true} if the
1273         *                                 {@code request_uri} parameter is
1274         *                                 supported, else {@code false}.
1275         */
1276        public void setSupportsRequestURIParam(final boolean requestURIParamSupported) {
1277
1278                this.requestURIParamSupported = requestURIParamSupported;
1279        }
1280        
1281        
1282        /**
1283         * Gets the requirement for the {@code request_uri} parameter 
1284         * pre-registration. Corresponds to the 
1285         * {@code require_request_uri_registration} metadata field.
1286         * 
1287         * @return {@code true} if the {@code request_uri} parameter values
1288         *         must be pre-registered, else {@code false}.
1289         */
1290        public boolean requiresRequestURIRegistration() {
1291                
1292                return requireRequestURIReg;
1293        }
1294
1295
1296        /**
1297         * Sets the requirement for the {@code request_uri} parameter
1298         * pre-registration. Corresponds to the
1299         * {@code require_request_uri_registration} metadata field.
1300         *
1301         * @param requireRequestURIReg {@code true} if the {@code request_uri}
1302         *                             parameter values must be pre-registered,
1303         *                             else {@code false}.
1304         */
1305        public void setRequiresRequestURIRegistration(final boolean requireRequestURIReg) {
1306
1307                this.requireRequestURIReg = requireRequestURIReg;
1308        }
1309
1310
1311        /**
1312         * Applies the OpenID Connect provider metadata defaults where no
1313         * values have been specified.
1314         *
1315         * <ul>
1316         *     <li>The response modes default to {@code ["query", "fragment"]}.
1317         *     <li>The grant types default to {@code ["authorization_code",
1318         *         "implicit"]}.
1319         *     <li>The token endpoint authentication methods default to
1320         *         {@code ["client_secret_basic"]}.
1321         *     <li>The claim types default to {@code ["normal]}.
1322         * </ul>
1323         */
1324        public void applyDefaults() {
1325
1326                if (rms == null) {
1327                        rms = new ArrayList<>(2);
1328                        rms.add(ResponseMode.QUERY);
1329                        rms.add(ResponseMode.FRAGMENT);
1330                }
1331
1332                if (gts == null) {
1333                        gts = new ArrayList<>(2);
1334                        gts.add(GrantType.AUTHORIZATION_CODE);
1335                        gts.add(GrantType.IMPLICIT);
1336                }
1337
1338                if (claimTypes == null) {
1339                        claimTypes = new ArrayList<>(1);
1340                        claimTypes.add(ClaimType.NORMAL);
1341                }
1342        }
1343
1344
1345        /**
1346         * Returns the JSON object representation of this OpenID Connect
1347         * provider metadata.
1348         *
1349         * @return The JSON object representation.
1350         */
1351        public JSONObject toJSONObject() {
1352
1353                JSONObject o = new JSONObject();
1354
1355                // Mandatory fields
1356
1357                o.put("issuer", issuer.getValue());
1358
1359                List<String> stringList = new ArrayList<>(subjectTypes.size());
1360
1361                for (SubjectType st: subjectTypes)
1362                        stringList.add(st.toString());
1363
1364                o.put("subject_types_supported", stringList);
1365
1366                o.put("jwks_uri", jwkSetURI.toString());
1367
1368                // Optional fields
1369
1370                if (authzEndpoint != null)
1371                        o.put("authorization_endpoint", authzEndpoint.toString());
1372
1373                if (tokenEndpoint != null)
1374                        o.put("token_endpoint", tokenEndpoint.toString());
1375
1376                if (userInfoEndpoint != null)
1377                        o.put("userinfo_endpoint", userInfoEndpoint.toString());
1378
1379                if (regEndpoint != null)
1380                        o.put("registration_endpoint", regEndpoint.toString());
1381
1382                if (checkSessionIframe != null)
1383                        o.put("check_session_iframe", checkSessionIframe.toString());
1384
1385                if (endSessionEndpoint != null)
1386                        o.put("end_session_endpoint", endSessionEndpoint.toString());
1387
1388                if (scope != null)
1389                        o.put("scopes_supported", scope.toStringList());
1390
1391                if (rts != null) {
1392
1393                        stringList = new ArrayList<>(rts.size());
1394
1395                        for (ResponseType rt: rts)
1396                                stringList.add(rt.toString());
1397
1398                        o.put("response_types_supported", stringList);
1399                }
1400
1401                if (rms != null) {
1402
1403                        stringList = new ArrayList<>(rms.size());
1404
1405                        for (ResponseMode rm: rms)
1406                                stringList.add(rm.getValue());
1407
1408                        o.put("response_modes_supported", stringList);
1409                }
1410
1411                if (gts != null) {
1412
1413                        stringList = new ArrayList<>(gts.size());
1414
1415                        for (GrantType gt: gts)
1416                                stringList.add(gt.toString());
1417
1418                        o.put("grant_types_supported", stringList);
1419                }
1420
1421                if (acrValues != null) {
1422
1423                        stringList = new ArrayList<>(acrValues.size());
1424
1425                        for (ACR acr: acrValues)
1426                                stringList.add(acr.getValue());
1427
1428                        o.put("acr_values_supported", stringList);
1429                }
1430
1431
1432                if (tokenEndpointAuthMethods != null) {
1433
1434                        stringList = new ArrayList<>(tokenEndpointAuthMethods.size());
1435
1436                        for (ClientAuthenticationMethod m: tokenEndpointAuthMethods)
1437                                stringList.add(m.getValue());
1438
1439                        o.put("token_endpoint_auth_methods_supported", stringList);
1440                }
1441
1442                if (tokenEndpointJWSAlgs != null) {
1443
1444                        stringList = new ArrayList<>(tokenEndpointJWSAlgs.size());
1445
1446                        for (JWSAlgorithm alg: tokenEndpointJWSAlgs)
1447                                stringList.add(alg.getName());
1448
1449                        o.put("token_endpoint_auth_signing_alg_values_supported", stringList);
1450                }
1451
1452                if (requestObjectJWSAlgs != null) {
1453
1454                        stringList = new ArrayList<>(requestObjectJWSAlgs.size());
1455
1456                        for (JWSAlgorithm alg: requestObjectJWSAlgs)
1457                                stringList.add(alg.getName());
1458
1459                        o.put("request_object_signing_alg_values_supported", stringList);
1460                }
1461
1462                if (requestObjectJWEAlgs != null) {
1463
1464                        stringList = new ArrayList<>(requestObjectJWEAlgs.size());
1465
1466                        for (JWEAlgorithm alg: requestObjectJWEAlgs)
1467                                stringList.add(alg.getName());
1468
1469                        o.put("request_object_encryption_alg_values_supported", stringList);
1470                }
1471
1472                if (requestObjectJWEEncs != null) {
1473
1474                        stringList = new ArrayList<>(requestObjectJWEEncs.size());
1475
1476                        for (EncryptionMethod m: requestObjectJWEEncs)
1477                                stringList.add(m.getName());
1478
1479                        o.put("request_object_encryption_enc_values_supported", stringList);
1480                }
1481
1482                if (idTokenJWSAlgs != null) {
1483
1484                        stringList = new ArrayList<>(idTokenJWSAlgs.size());
1485
1486                        for (JWSAlgorithm alg: idTokenJWSAlgs)
1487                                stringList.add(alg.getName());
1488
1489                        o.put("id_token_signing_alg_values_supported", stringList);
1490                }
1491
1492                if (idTokenJWEAlgs != null) {
1493
1494                        stringList = new ArrayList<>(idTokenJWEAlgs.size());
1495
1496                        for (JWEAlgorithm alg: idTokenJWEAlgs)
1497                                stringList.add(alg.getName());
1498
1499                        o.put("id_token_encryption_alg_values_supported", stringList);
1500                }
1501
1502                if (idTokenJWEEncs != null) {
1503
1504                        stringList = new ArrayList<>(idTokenJWEEncs.size());
1505
1506                        for (EncryptionMethod m: idTokenJWEEncs)
1507                                stringList.add(m.getName());
1508
1509                        o.put("id_token_encryption_enc_values_supported", stringList);
1510                }
1511
1512                if (userInfoJWSAlgs != null) {
1513
1514                        stringList = new ArrayList<>(userInfoJWSAlgs.size());
1515
1516                        for (JWSAlgorithm alg: userInfoJWSAlgs)
1517                                stringList.add(alg.getName());
1518
1519                        o.put("userinfo_signing_alg_values_supported", stringList);
1520                }
1521
1522                if (userInfoJWEAlgs != null) {
1523
1524                        stringList = new ArrayList<>(userInfoJWEAlgs.size());
1525
1526                        for (JWEAlgorithm alg: userInfoJWEAlgs)
1527                                stringList.add(alg.getName());
1528
1529                        o.put("userinfo_encryption_alg_values_supported", stringList);
1530                }
1531
1532                if (userInfoJWEEncs != null) {
1533
1534                        stringList = new ArrayList<>(userInfoJWEEncs.size());
1535
1536                        for (EncryptionMethod m: userInfoJWEEncs)
1537                                stringList.add(m.getName());
1538
1539                        o.put("userinfo_encryption_enc_values_supported", stringList);
1540                }
1541
1542                if (displays != null) {
1543
1544                        stringList = new ArrayList<>(displays.size());
1545
1546                        for (Display d: displays)
1547                                stringList.add(d.toString());
1548
1549                        o.put("display_values_supported", stringList);
1550                }
1551
1552                if (claimTypes != null) {
1553
1554                        stringList = new ArrayList<>(claimTypes.size());
1555
1556                        for (ClaimType ct: claimTypes)
1557                                stringList.add(ct.toString());
1558
1559                        o.put("claim_types_supported", stringList);
1560                }
1561
1562                if (claims != null)
1563                        o.put("claims_supported", claims);
1564
1565                if (claimsLocales != null) {
1566
1567                        stringList = new ArrayList<>(claimsLocales.size());
1568
1569                        for (LangTag l: claimsLocales)
1570                                stringList.add(l.toString());
1571
1572                        o.put("claims_locales_supported", stringList);
1573                }
1574
1575                if (uiLocales != null) {
1576
1577                        stringList = new ArrayList<>(uiLocales.size());
1578
1579                        for (LangTag l: uiLocales)
1580                                stringList.add(l.toString());
1581
1582                        o.put("ui_locales_supported", stringList);
1583                }
1584
1585                if (serviceDocsURI != null)
1586                        o.put("service_documentation", serviceDocsURI.toString());
1587
1588                if (policyURI != null)
1589                        o.put("op_policy_uri", policyURI.toString());
1590
1591                if (tosURI != null)
1592                        o.put("op_tos_uri", tosURI.toString());
1593
1594                o.put("claims_parameter_supported", claimsParamSupported);
1595
1596                o.put("request_parameter_supported", requestParamSupported);
1597
1598                o.put("request_uri_parameter_supported", requestURIParamSupported);
1599
1600                o.put("require_request_uri_registration", requireRequestURIReg);
1601
1602                return o;
1603        }
1604
1605
1606
1607        /**
1608         * Parses an OpenID Connect provider metadata from the specified JSON 
1609         * object.
1610         *
1611         * @param jsonObject The JSON object to parse. Must not be 
1612         *                   {@code null}.
1613         *
1614         * @return The OpenID Connect provider metadata.
1615         *
1616         * @throws ParseException If the JSON object couldn't be parsed to an
1617         *                        OpenID Connect provider metadata.
1618         */
1619        public static OIDCProviderMetadata parse(final JSONObject jsonObject)
1620                throws ParseException {
1621
1622                // Parse issuer and subject_types_supported first
1623                
1624                List<SubjectType> subjectTypes = new ArrayList<>();
1625                
1626                for (String v: JSONObjectUtils.getStringArray(jsonObject, "subject_types_supported")) {
1627                        subjectTypes.add(SubjectType.parse(v));
1628                }
1629                
1630                Issuer issuer = new Issuer(JSONObjectUtils.getURI(jsonObject, "issuer").toString());
1631
1632                URI jwkSetURI = JSONObjectUtils.getURI(jsonObject, "jwks_uri");
1633                
1634                
1635                OIDCProviderMetadata op = new OIDCProviderMetadata(issuer, Collections.unmodifiableList(subjectTypes), jwkSetURI);
1636
1637                // Endpoints
1638                if (jsonObject.containsKey("authorization_endpoint"))
1639                        op.authzEndpoint = JSONObjectUtils.getURI(jsonObject, "authorization_endpoint");
1640
1641                if (jsonObject.containsKey("token_endpoint"))
1642                        op.tokenEndpoint = JSONObjectUtils.getURI(jsonObject, "token_endpoint");
1643
1644                if (jsonObject.containsKey("userinfo_endpoint"))
1645                        op.userInfoEndpoint = JSONObjectUtils.getURI(jsonObject, "userinfo_endpoint");
1646                
1647                if (jsonObject.containsKey("registration_endpoint"))
1648                        op.regEndpoint = JSONObjectUtils.getURI(jsonObject, "registration_endpoint");
1649                
1650                if (jsonObject.containsKey("check_session_iframe"))
1651                        op.checkSessionIframe = JSONObjectUtils.getURI(jsonObject, "check_session_iframe");
1652                
1653                if (jsonObject.containsKey("end_session_endpoint"))
1654                        op.endSessionEndpoint = JSONObjectUtils.getURI(jsonObject, "end_session_endpoint");
1655
1656                // OIDC capabilities
1657                if (jsonObject.containsKey("scopes_supported")) {
1658
1659                        op.scope = new Scope();
1660
1661                        for (String v: JSONObjectUtils.getStringArray(jsonObject, "scopes_supported")) {
1662
1663                                if (v != null)
1664                                        op.scope.add(new Scope.Value(v));
1665                        }
1666                }
1667
1668                if (jsonObject.containsKey("response_types_supported")) {
1669
1670                        op.rts = new ArrayList<>();
1671
1672                        for (String v: JSONObjectUtils.getStringArray(jsonObject, "response_types_supported")) {
1673
1674                                if (v != null)
1675                                        op.rts.add(ResponseType.parse(v));
1676                        }
1677                }
1678
1679                if (jsonObject.containsKey("response_modes_supported")) {
1680
1681                        op.rms = new ArrayList<>();
1682
1683                        for (String v: JSONObjectUtils.getStringArray(jsonObject, "response_modes_supported")) {
1684
1685                                if (v != null)
1686                                        op.rms.add(new ResponseMode(v));
1687                        }
1688                }
1689                
1690                if (jsonObject.containsKey("grant_types_supported")) {
1691                        
1692                        op.gts = new ArrayList<>();
1693                        
1694                        for (String v: JSONObjectUtils.getStringArray(jsonObject, "grant_types_supported")) {
1695                                
1696                                if (v != null)
1697                                        op.gts.add(GrantType.parse(v));
1698                        }
1699                }
1700
1701                if (jsonObject.containsKey("acr_values_supported")) {
1702
1703                        op.acrValues = new ArrayList<>();
1704
1705                        for (String v: JSONObjectUtils.getStringArray(jsonObject, "acr_values_supported")) {
1706
1707                                if (v != null)
1708                                        op.acrValues.add(new ACR(v));
1709                        }
1710                }
1711
1712                if (jsonObject.containsKey("token_endpoint_auth_methods_supported")) {
1713                        
1714                        op.tokenEndpointAuthMethods = new ArrayList<>();
1715                        
1716                        for (String v: JSONObjectUtils.getStringArray(jsonObject, "token_endpoint_auth_methods_supported")) {
1717                                
1718                                if (v != null)
1719                                        op.tokenEndpointAuthMethods.add(new ClientAuthenticationMethod(v));
1720                        }
1721                }
1722                
1723                if (jsonObject.containsKey("token_endpoint_auth_signing_alg_values_supported")) {
1724                        
1725                        op.tokenEndpointJWSAlgs = new ArrayList<>();
1726                        
1727                        for (String v: JSONObjectUtils.getStringArray(jsonObject, "token_endpoint_auth_signing_alg_values_supported")) {
1728
1729                                if (v != null && v.equals(Algorithm.NONE.getName()))
1730                                        throw new ParseException("The none algorithm is not accepted");
1731                                
1732                                if (v != null)
1733                                        op.tokenEndpointJWSAlgs.add(new JWSAlgorithm(v));
1734                        }
1735                }
1736                
1737                
1738                // OpenID Connect request object
1739
1740                if (jsonObject.containsKey("request_object_signing_alg_values_supported")) {
1741
1742                        op.requestObjectJWSAlgs = new ArrayList<>();
1743
1744                        for (String v: JSONObjectUtils.getStringArray(jsonObject, "request_object_signing_alg_values_supported")) {
1745
1746                                if (v != null)
1747                                        op.requestObjectJWSAlgs.add(new JWSAlgorithm(v));
1748                        }
1749                }
1750
1751
1752                if (jsonObject.containsKey("request_object_encryption_alg_values_supported")) {
1753
1754                        op.requestObjectJWEAlgs = new ArrayList<>();
1755
1756                        for (String v: JSONObjectUtils.getStringArray(jsonObject, "request_object_encryption_alg_values_supported")) {
1757
1758                                if (v != null)
1759                                        op.requestObjectJWEAlgs.add(new JWEAlgorithm(v));
1760                        }
1761                }
1762
1763
1764                if (jsonObject.containsKey("request_object_encryption_enc_values_supported")) {
1765
1766                        op.requestObjectJWEEncs = new ArrayList<>();
1767
1768                        for (String v: JSONObjectUtils.getStringArray(jsonObject, "request_object_encryption_enc_values_supported")) {
1769
1770                                if (v != null)
1771                                        op.requestObjectJWEEncs.add(new EncryptionMethod(v));
1772                        }
1773                }
1774                
1775                
1776                // ID token
1777
1778                if (jsonObject.containsKey("id_token_signing_alg_values_supported")) {
1779
1780                        op.idTokenJWSAlgs = new ArrayList<>();
1781
1782                        for (String v: JSONObjectUtils.getStringArray(jsonObject, "id_token_signing_alg_values_supported")) {
1783
1784                                if (v != null)
1785                                        op.idTokenJWSAlgs.add(new JWSAlgorithm(v));
1786                        }
1787                }
1788
1789
1790                if (jsonObject.containsKey("id_token_encryption_alg_values_supported")) {
1791
1792                        op.idTokenJWEAlgs = new ArrayList<>();
1793
1794                        for (String v: JSONObjectUtils.getStringArray(jsonObject, "id_token_encryption_alg_values_supported")) {
1795
1796                                if (v != null)
1797                                        op.idTokenJWEAlgs.add(new JWEAlgorithm(v));
1798                        }
1799                }
1800
1801
1802                if (jsonObject.containsKey("id_token_encryption_enc_values_supported")) {
1803
1804                        op.idTokenJWEEncs = new ArrayList<>();
1805
1806                        for (String v: JSONObjectUtils.getStringArray(jsonObject, "id_token_encryption_enc_values_supported")) {
1807
1808                                if (v != null)
1809                                        op.idTokenJWEEncs.add(new EncryptionMethod(v));
1810                        }
1811                }
1812
1813                // UserInfo
1814
1815                if (jsonObject.containsKey("userinfo_signing_alg_values_supported")) {
1816
1817                        op.userInfoJWSAlgs = new ArrayList<>();
1818
1819                        for (String v: JSONObjectUtils.getStringArray(jsonObject, "userinfo_signing_alg_values_supported")) {
1820
1821                                if (v != null)
1822                                        op.userInfoJWSAlgs.add(new JWSAlgorithm(v));
1823                        }
1824                }
1825
1826
1827                if (jsonObject.containsKey("userinfo_encryption_alg_values_supported")) {
1828
1829                        op.userInfoJWEAlgs = new ArrayList<>();
1830
1831                        for (String v: JSONObjectUtils.getStringArray(jsonObject, "userinfo_encryption_alg_values_supported")) {
1832
1833                                if (v != null)
1834                                        op.userInfoJWEAlgs.add(new JWEAlgorithm(v));
1835                        }
1836                }
1837
1838
1839                if (jsonObject.containsKey("userinfo_encryption_enc_values_supported")) {
1840
1841                        op.userInfoJWEEncs = new ArrayList<>();
1842
1843                        for (String v: JSONObjectUtils.getStringArray(jsonObject, "userinfo_encryption_enc_values_supported")) {
1844
1845                                        if (v != null)
1846                                                op.userInfoJWEEncs.add(new EncryptionMethod(v));
1847                        }
1848                }
1849
1850                
1851                // Misc
1852
1853                if (jsonObject.containsKey("display_values_supported")) {
1854
1855                        op.displays = new ArrayList<>();
1856
1857                        for (String v: JSONObjectUtils.getStringArray(jsonObject, "display_values_supported")) {
1858
1859                                if (v != null)
1860                                        op.displays.add(Display.parse(v));
1861                        }
1862                }
1863                
1864                if (jsonObject.containsKey("claim_types_supported")) {
1865                        
1866                        op.claimTypes = new ArrayList<>();
1867                        
1868                        for (String v: JSONObjectUtils.getStringArray(jsonObject, "claim_types_supported")) {
1869                                
1870                                if (v != null)
1871                                        op.claimTypes.add(ClaimType.parse(v));
1872                        }
1873                }
1874
1875
1876                if (jsonObject.containsKey("claims_supported")) {
1877
1878                        op.claims = new ArrayList<>();
1879
1880                        for (String v: JSONObjectUtils.getStringArray(jsonObject, "claims_supported")) {
1881
1882                                if (v != null)
1883                                        op.claims.add(v);
1884                        }
1885                }
1886                
1887                if (jsonObject.containsKey("claims_locales_supported")) {
1888                        
1889                        op.claimsLocales = new ArrayList<>();
1890                        
1891                        for (String v : JSONObjectUtils.getStringArray(jsonObject, "claims_locales_supported")) {
1892                                
1893                                if (v != null) {
1894                                        
1895                                        try {
1896                                                op.claimsLocales.add(LangTag.parse(v));
1897                                        
1898                                        } catch (LangTagException e) {
1899                                                
1900                                                throw new ParseException("Invalid claims_locales_supported field: " + e.getMessage(), e);
1901                                        }
1902                                }
1903                        }
1904                }
1905                
1906                if (jsonObject.containsKey("ui_locales_supported")) {
1907                        
1908                        op.uiLocales = new ArrayList<>();
1909                        
1910                        for (String v : JSONObjectUtils.getStringArray(jsonObject, "ui_locales_supported")) {
1911                                
1912                                if (v != null) {
1913                                        
1914                                        try {
1915                                                op.uiLocales.add(LangTag.parse(v));
1916                                        
1917                                        } catch (LangTagException e) {
1918                                                
1919                                                throw new ParseException("Invalid ui_locales_supported field: " + e.getMessage(), e);
1920                                        }
1921                                }
1922                        }
1923                }
1924
1925
1926                if (jsonObject.containsKey("service_documentation"))
1927                        op.serviceDocsURI = JSONObjectUtils.getURI(jsonObject, "service_documentation");
1928                
1929                if (jsonObject.containsKey("op_policy_uri"))
1930                        op.policyURI = JSONObjectUtils.getURI(jsonObject, "op_policy_uri");
1931                
1932                if (jsonObject.containsKey("op_tos_uri"))
1933                        op.tosURI = JSONObjectUtils.getURI(jsonObject, "op_tos_uri");
1934                
1935                if (jsonObject.containsKey("claims_parameter_supported"))
1936                        op.claimsParamSupported = JSONObjectUtils.getBoolean(jsonObject, "claims_parameter_supported");
1937                
1938                if (jsonObject.containsKey("request_parameter_supported"))
1939                        op.requestParamSupported = JSONObjectUtils.getBoolean(jsonObject, "request_parameter_supported");
1940                
1941                if (jsonObject.containsKey("request_uri_parameter_supported"))
1942                        op.requestURIParamSupported = JSONObjectUtils.getBoolean(jsonObject, "request_uri_parameter_supported");
1943                
1944                if (jsonObject.containsKey("require_request_uri_registration"))
1945                        op.requireRequestURIReg = JSONObjectUtils.getBoolean(jsonObject, "require_request_uri_registration");
1946
1947                return op;
1948        }
1949
1950
1951        /**
1952         * Parses an OpenID Connect provider metadata from the specified JSON 
1953         * object string.
1954         *
1955         * @param s The JSON object sting to parse. Must not be {@code null}.
1956         *
1957         * @return The OpenID Connect provider metadata.
1958         *
1959         * @throws ParseException If the JSON object string couldn't be parsed
1960         *                        to an OpenID Connect provider metadata.
1961         */
1962        public static OIDCProviderMetadata parse(final String s)
1963                throws ParseException {
1964
1965                return parse(JSONObjectUtils.parse(s));
1966        }
1967}