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