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