001package com.nimbusds.openid.connect.sdk.rp;
002
003
004import java.net.URI;
005import java.net.URISyntaxException;
006import java.util.*;
007
008import net.minidev.json.JSONArray;
009import net.minidev.json.JSONObject;
010
011import com.nimbusds.jose.EncryptionMethod;
012import com.nimbusds.jose.JWEAlgorithm;
013import com.nimbusds.jose.JWSAlgorithm;
014
015import com.nimbusds.oauth2.sdk.ParseException;
016import com.nimbusds.oauth2.sdk.client.ClientMetadata;
017import com.nimbusds.oauth2.sdk.util.JSONObjectUtils;
018
019import com.nimbusds.openid.connect.sdk.SubjectType;
020import com.nimbusds.openid.connect.sdk.claims.ACR;
021
022
023/**
024 * OpenID Connect client metadata.
025 *
026 * <p>Related specifications:
027 *
028 * <ul>
029 *     <li>OpenID Connect Dynamic Client Registration 1.0, section 2.
030 *     <li>OpenID Connect Session Management 1.0, section 5.1.1.
031 *     <li>OAuth 2.0 Dynamic Client Registration Protocol (RFC 7591), section
032 *         2.
033 * </ul>
034 */
035public class OIDCClientMetadata extends ClientMetadata {
036
037
038        /**
039         * The registered parameter names.
040         */
041        private static final Set<String> REGISTERED_PARAMETER_NAMES;
042
043
044        /**
045         * Initialises the registered parameter name set.
046         */
047        static {
048                // Start with the base OAuth 2.0 client params
049                Set<String> p = new HashSet<>(ClientMetadata.getRegisteredParameterNames());
050
051                // OIDC params
052                p.add("application_type");
053                p.add("subject_type");
054                p.add("sector_identifier_uri");
055                p.add("request_uris");
056                p.add("request_object_signing_alg");
057                p.add("request_object_encryption_alg");
058                p.add("request_object_encryption_enc");
059                p.add("id_token_signed_response_alg");
060                p.add("id_token_encrypted_response_alg");
061                p.add("id_token_encrypted_response_enc");
062                p.add("userinfo_signed_response_alg");
063                p.add("userinfo_encrypted_response_alg");
064                p.add("userinfo_encrypted_response_enc");
065                p.add("default_max_age");
066                p.add("require_auth_time");
067                p.add("default_acr_values");
068                p.add("initiate_login_uri");
069
070                // OIDC session
071                p.add("post_logout_redirect_uris");
072
073                REGISTERED_PARAMETER_NAMES = Collections.unmodifiableSet(p);
074        }
075
076
077        /**
078         * The client application type.
079         */
080        private ApplicationType applicationType;
081
082
083        /**
084         * The subject identifier type for responses to this client.
085         */
086        private SubjectType subjectType;
087
088
089        /**
090         * Sector identifier URI.
091         */
092        private URI sectorIDURI;
093        
094        
095        /**
096         * Pre-registered OpenID Connect request URIs.
097         */
098        private Set<URI> requestObjectURIs;
099
100
101        /**
102         * The JSON Web Signature (JWS) algorithm required for the OpenID 
103         * Connect request objects sent by this client.
104         */
105        private JWSAlgorithm requestObjectJWSAlg;
106
107
108        /**
109         * The JSON Web Encryption (JWE) algorithm required for the OpenID
110         * Connect request objects sent by this client.
111         */
112        private JWEAlgorithm requestObjectJWEAlg;
113
114
115        /**
116         * The JSON Web Encryption (JWE) method required for the OpenID Connect
117         * request objects sent by this client.
118         */
119        private EncryptionMethod requestObjectJWEEnc;
120
121
122        /**
123         * The JSON Web Signature (JWS) algorithm required for the ID Tokens
124         * issued to this client.
125         */
126        private JWSAlgorithm idTokenJWSAlg;
127
128
129        /**
130         * The JSON Web Encryption (JWE) algorithm required for the ID Tokens
131         * issued to this client.
132         */
133        private JWEAlgorithm idTokenJWEAlg;
134
135
136        /**
137         * The JSON Web Encryption (JWE) method required for the ID Tokens
138         * issued to this client.
139         */
140        private EncryptionMethod idTokenJWEEnc;
141
142
143        /**
144         * The JSON Web Signature (JWS) algorithm required for the UserInfo
145         * responses to this client.
146         */
147        private JWSAlgorithm userInfoJWSAlg;
148
149
150        /**
151         * The JSON Web Encryption (JWE) algorithm required for the UserInfo
152         * responses to this client.
153         */
154        private JWEAlgorithm userInfoJWEAlg;
155
156
157        /**
158         * The JSON Web Encryption (JWE) method required for the UserInfo
159         * responses to this client.
160         */
161        private EncryptionMethod userInfoJWEEnc;
162
163
164        /**
165         * The default max authentication age, in seconds. If not specified 0.
166         */
167        private int defaultMaxAge;
168
169
170        /**
171         * If {@code true} the {@code auth_time} claim in the ID Token is
172         * required by default.
173         */
174        private boolean requiresAuthTime;
175
176
177        /**
178         * The default Authentication Context Class Reference (ACR) values, by
179         * order of preference.
180         */
181        private List<ACR> defaultACRs;
182
183
184        /**
185         * Authorisation server initiated login HTTPS URI.
186         */
187        private URI initiateLoginURI;
188
189
190        /**
191         * Logout redirection URIs.
192         */
193        private Set<URI> postLogoutRedirectURIs;
194
195
196        /** 
197         * Creates a new OpenID Connect client metadata instance.
198         */
199        public OIDCClientMetadata() {
200
201                super();
202        }
203        
204        
205        /**
206         * Creates a new OpenID Connect client metadata instance from the
207         * specified base OAuth 2.0 client metadata.
208         * 
209         * @param metadata The base OAuth 2.0 client metadata. Must not be
210         *                 {@code null}.
211         */
212        public OIDCClientMetadata(final ClientMetadata metadata) {
213                
214                super(metadata);
215        }
216
217
218        /**
219         * Gets the registered (standard) OpenID Connect client metadata
220         * parameter names.
221         *
222         * @return The registered OpenID Connect parameter names, as an
223         *         unmodifiable set.
224         */
225        public static Set<String> getRegisteredParameterNames() {
226
227                return REGISTERED_PARAMETER_NAMES;
228        }
229
230
231        /**
232         * Gets the client application type. Corresponds to the
233         * {@code application_type} client metadata field.
234         *
235         * @return The client application type, {@code null} if not specified.
236         */
237        public ApplicationType getApplicationType() {
238
239                return applicationType;
240        }
241
242
243        /**
244         * Sets the client application type. Corresponds to the
245         * {@code application_type} client metadata field.
246         *
247         * @param applicationType The client application type, {@code null} if
248         *                        not specified.
249         */
250        public void setApplicationType(final ApplicationType applicationType) {
251
252                this.applicationType = applicationType;
253        }
254
255
256        /**
257         * Gets the subject identifier type for responses to this client. 
258         * Corresponds to the {@code subject_type} client metadata field.
259         *
260         * @return The subject identifier type, {@code null} if not specified.
261         */
262        public SubjectType getSubjectType() {
263
264                return subjectType;
265        }
266
267
268        /**
269         * Sets the subject identifier type for responses to this client. 
270         * Corresponds to the {@code subject_type} client metadata field.
271         *
272         * @param subjectType The subject identifier type, {@code null} if not 
273         *                    specified.
274         */
275        public void setSubjectType(final SubjectType subjectType) {
276
277                this.subjectType = subjectType;
278        }
279
280
281        /**
282         * Gets the sector identifier URI. Corresponds to the 
283         * {@code sector_identifier_uri} client metadata field.
284         *
285         * @return The sector identifier URI, {@code null} if not specified.
286         */
287        public URI getSectorIDURI() {
288
289                return sectorIDURI;
290        }
291
292
293        /**
294         * Sets the sector identifier URI. Corresponds to the 
295         * {@code sector_identifier_uri} client metadata field.
296         *
297         * @param sectorIDURI The sector identifier URI, {@code null} if not 
298         *                    specified.
299         */
300        public void setSectorIDURI(final URI sectorIDURI) {
301
302                this.sectorIDURI = sectorIDURI;
303        }
304        
305        
306        /**
307         * Gets the pre-registered OpenID Connect request object URIs.
308         * Corresponds to the {@code request_uris} client metadata field.
309         * 
310         * @return The request object URIs, {@code null} if not specified.
311         */
312        public Set<URI> getRequestObjectURIs() {
313                
314                return requestObjectURIs;
315        }
316        
317        
318        /**
319         * Sets the pre-registered OpenID Connect request object URIs.
320         * Corresponds to the {@code request_uris} client metadata field.
321         *
322         * @param requestObjectURIs The request object URIs, {@code null} if
323         *                          not specified.
324         */
325        public void setRequestObjectURIs(final Set<URI> requestObjectURIs) {
326
327                this.requestObjectURIs = requestObjectURIs;
328        }
329
330
331        /**
332         * Gets the JSON Web Signature (JWS) algorithm required for the OpenID 
333         * Connect request objects sent by this client. Corresponds to the 
334         * {@code request_object_signing_alg} client metadata field.
335         *
336         * @return The JWS algorithm, {@code null} if not specified.
337         */
338        public JWSAlgorithm getRequestObjectJWSAlg() {
339
340                return requestObjectJWSAlg;
341        }
342
343
344        /**
345         * Sets the JSON Web Signature (JWS) algorithm required for the OpenID 
346         * Connect request objects sent by this client. Corresponds to the 
347         * {@code request_object_signing_alg} client metadata field.
348         *
349         * @param requestObjectJWSAlg The JWS algorithm, {@code null} if not 
350         *                            specified.
351         */
352        public void setRequestObjectJWSAlg(final JWSAlgorithm requestObjectJWSAlg) {
353
354                this.requestObjectJWSAlg = requestObjectJWSAlg;
355        }
356
357
358        /**
359         * Gets the JSON Web Encryption (JWE) algorithm required for the OpenID
360         * Connect request objects sent by this client. Corresponds to the
361         * {@code request_object_encryption_alg} client metadata field.
362         *
363         * @return The JWE algorithm, {@code null} if not specified.
364         */
365        public JWEAlgorithm getRequestObjectJWEAlg() {
366
367                return requestObjectJWEAlg;
368        }
369
370
371        /**
372         * Sets the JSON Web Encryption (JWE) algorithm required for the OpenID
373         * Connect request objects sent by this client. Corresponds to the
374         * {@code request_object_encryption_alg} client metadata field.
375         *
376         * @param requestObjectJWEAlg The JWE algorithm, {@code null} if not
377         *                            specified.
378         */
379        public void setRequestObjectJWEAlg(final JWEAlgorithm requestObjectJWEAlg) {
380
381                this.requestObjectJWEAlg = requestObjectJWEAlg;
382        }
383
384
385        /**
386         * Gets the JSON Web Encryption (JWE) method required for the OpenID
387         * Connect request objects sent by this client. Corresponds to the
388         * {@code request_object_encryption_enc} client metadata field.
389         *
390         * @return The JWE method, {@code null} if not specified.
391         */
392        public EncryptionMethod getRequestObjectJWEEnc() {
393
394                return requestObjectJWEEnc;
395        }
396
397
398        /**
399         * Sets the JSON Web Encryption (JWE) method required for the OpenID
400         * Connect request objects sent by this client. Corresponds to the
401         * {@code request_object_encryption_enc} client metadata field.
402         *
403         * @param requestObjectJWEEnc The JWE method, {@code null} if not
404         *                            specified.
405         */
406        public void setRequestObjectJWEEnc(final EncryptionMethod requestObjectJWEEnc) {
407
408                this.requestObjectJWEEnc = requestObjectJWEEnc;
409        }
410
411
412        /**
413         * Gets the JSON Web Signature (JWS) algorithm required for the ID 
414         * Tokens issued to this client. Corresponds to the 
415         * {@code id_token_signed_response_alg} client metadata field.
416         *
417         * @return The JWS algorithm, {@code null} if not specified.
418         */
419        public JWSAlgorithm getIDTokenJWSAlg() {
420
421                return idTokenJWSAlg;
422        }
423
424
425        /**
426         * Sets the JSON Web Signature (JWS) algorithm required for the ID 
427         * Tokens issued to this client. Corresponds to the 
428         * {@code id_token_signed_response_alg} client metadata field.
429         *
430         * @param idTokenJWSAlg The JWS algorithm, {@code null} if not 
431         *                      specified.
432         */
433        public void setIDTokenJWSAlg(final JWSAlgorithm idTokenJWSAlg) {
434
435                this.idTokenJWSAlg = idTokenJWSAlg;
436        }
437
438
439        /**
440         * Gets the JSON Web Encryption (JWE) algorithm required for the ID 
441         * Tokens issued to this client. Corresponds to the 
442         * {@code id_token_encrypted_response_alg} client metadata field.
443         *
444         * @return The JWE algorithm, {@code null} if not specified.
445         */
446        public JWEAlgorithm getIDTokenJWEAlg() {
447
448                return idTokenJWEAlg;
449        }
450
451
452        /**
453         * Sets the JSON Web Encryption (JWE) algorithm required for the ID 
454         * Tokens issued to this client. Corresponds to the 
455         * {@code id_token_encrypted_response_alg} client metadata field.
456         *
457         * @param idTokenJWEAlg The JWE algorithm, {@code null} if not 
458         *                      specified.
459         */
460        public void setIDTokenJWEAlg(final JWEAlgorithm idTokenJWEAlg) {
461
462                this.idTokenJWEAlg = idTokenJWEAlg;
463        }
464
465
466        /**
467         * Gets the JSON Web Encryption (JWE) method required for the ID Tokens
468         * issued to this client. Corresponds to the 
469         * {@code id_token_encrypted_response_enc} client metadata field.
470         *
471         * @return The JWE method, {@code null} if not specified.
472         */
473        public EncryptionMethod getIDTokenJWEEnc() {
474
475                return idTokenJWEEnc;
476        }
477
478
479        /**
480         * Sets the JSON Web Encryption (JWE) method required for the ID Tokens
481         * issued to this client. Corresponds to the 
482         * {@code id_token_encrypted_response_enc} client metadata field.
483         *
484         * @param idTokenJWEEnc The JWE method, {@code null} if not specified.
485         */
486        public void setIDTokenJWEEnc(final EncryptionMethod idTokenJWEEnc) {
487
488                this.idTokenJWEEnc = idTokenJWEEnc;
489        }
490
491
492        /**
493         * Gets the JSON Web Signature (JWS) algorithm required for the 
494         * UserInfo responses to this client. Corresponds to the 
495         * {@code userinfo_signed_response_alg} client metadata field.
496         *
497         * @return The JWS algorithm, {@code null} if not specified.
498         */
499        public JWSAlgorithm getUserInfoJWSAlg() {
500
501                return userInfoJWSAlg;
502        }
503
504
505        /**
506         * Sets the JSON Web Signature (JWS) algorithm required for the 
507         * UserInfo responses to this client. Corresponds to the
508         * {@code userinfo_signed_response_alg} client metadata field.
509         *
510         * @param userInfoJWSAlg The JWS algorithm, {@code null} if not 
511         *                       specified.
512         */
513        public void setUserInfoJWSAlg(final JWSAlgorithm userInfoJWSAlg) {
514
515                this.userInfoJWSAlg = userInfoJWSAlg;
516        }
517
518
519        /**
520         * Gets the JSON Web Encryption (JWE) algorithm required for the 
521         * UserInfo responses to this client. Corresponds to the 
522         * {@code userinfo_encrypted_response_alg} client metadata field.
523         *
524         * @return The JWE algorithm, {@code null} if not specified.
525         */
526        public JWEAlgorithm getUserInfoJWEAlg() {
527
528                return userInfoJWEAlg;
529        }
530
531
532        /**
533         * Sets the JSON Web Encryption (JWE) algorithm required for the 
534         * UserInfo responses to this client. Corresponds to the 
535         * {@code userinfo_encrypted_response_alg} client metadata field.
536         *
537         * @param userInfoJWEAlg The JWE algorithm, {@code null} if not
538         *                       specified.
539         */
540        public void setUserInfoJWEAlg(final JWEAlgorithm userInfoJWEAlg) {
541
542                this.userInfoJWEAlg = userInfoJWEAlg;
543        }
544
545
546        /**
547         * Gets the JSON Web Encryption (JWE) method required for the UserInfo
548         * responses to this client. Corresponds to the 
549         * {@code userinfo_encrypted_response_enc} client metadata field.
550         *
551         * @return The JWE method, {@code null} if not specified.
552         */
553        public EncryptionMethod getUserInfoJWEEnc() {
554
555                return userInfoJWEEnc;
556        }
557
558
559        /**
560         * Sets the JSON Web Encryption (JWE) method required for the UserInfo
561         * responses to this client. Corresponds to the 
562         * {@code userinfo_encrypted_response_enc} client metadata field.
563         *
564         * @param userInfoJWEEnc The JWE method, {@code null} if not specified.
565         */
566        public void setUserInfoJWEEnc(final EncryptionMethod userInfoJWEEnc) {
567
568                this.userInfoJWEEnc = userInfoJWEEnc;
569        }
570
571
572        /**
573         * Gets the default maximum authentication age. Corresponds to the 
574         * {@code default_max_age} client metadata field.
575         *
576         * @return The default max authentication age, in seconds. If not
577         *         specified 0.
578         */
579        public int getDefaultMaxAge() {
580
581                return defaultMaxAge;
582        }
583
584
585        /**
586         * Sets the default maximum authentication age. Corresponds to the 
587         * {@code default_max_age} client metadata field.
588         *
589         * @param defaultMaxAge The default max authentication age, in seconds.
590         *                      If not specified 0.
591         */
592        public void setDefaultMaxAge(final int defaultMaxAge) {
593
594                this.defaultMaxAge = defaultMaxAge;
595        }
596
597
598        /**
599         * Gets the default requirement for the {@code auth_time} claim in the
600         * ID Token. Corresponds to the {@code require_auth_time} client 
601         * metadata field.
602         *
603         * @return If {@code true} the {@code auth_Time} claim in the ID Token 
604         *         is required by default.
605         */
606        public boolean requiresAuthTime() {
607
608                return requiresAuthTime;
609        }
610
611
612        /**
613         * Sets the default requirement for the {@code auth_time} claim in the
614         * ID Token. Corresponds to the {@code require_auth_time} client 
615         * metadata field.
616         *
617         * @param requiresAuthTime If {@code true} the {@code auth_Time} claim 
618         *                         in the ID Token is required by default.
619         */
620        public void requiresAuthTime(final boolean requiresAuthTime) {
621
622                this.requiresAuthTime = requiresAuthTime;
623        }
624
625
626        /**
627         * Gets the default Authentication Context Class Reference (ACR) 
628         * values. Corresponds to the {@code default_acr_values} client 
629         * metadata field.
630         *
631         * @return The default ACR values, by order of preference, 
632         *         {@code null} if not specified.
633         */
634        public List<ACR> getDefaultACRs() {
635
636                return defaultACRs;
637        }
638
639
640        /**
641         * Sets the default Authentication Context Class Reference (ACR)
642         * values. Corresponds to the {@code default_acr_values} client 
643         * metadata field.
644         *
645         * @param defaultACRs The default ACRs, by order of preference, 
646         *                    {@code null} if not specified.
647         */
648        public void setDefaultACRs(final List<ACR> defaultACRs) {
649
650                this.defaultACRs = defaultACRs;
651        }
652
653
654        /**
655         * Gets the HTTPS URI that the authorisation server can call to
656         * initiate a login at the client. Corresponds to the 
657         * {@code initiate_login_uri} client metadata field.
658         *
659         * @return The login URI, {@code null} if not specified.
660         */
661        public URI getInitiateLoginURI() {
662
663                return initiateLoginURI;
664        }
665
666
667        /**
668         * Sets the HTTPS URI that the authorisation server can call to
669         * initiate a login at the client. Corresponds to the 
670         * {@code initiate_login_uri} client metadata field.
671         *
672         * @param loginURI The login URI, {@code null} if not specified.
673         */
674        public void setInitiateLoginURI(final URI loginURI) {
675
676                this.initiateLoginURI = loginURI;
677        }
678
679
680        /**
681         * Gets the post logout redirection URIs. Corresponds to the
682         * {@code post_logout_redirect_uris} client metadata field.
683         *
684         * @return The logout redirection URIs, {@code null} if not specified.
685         */
686        public Set<URI> getPostLogoutRedirectionURIs() {
687
688                return postLogoutRedirectURIs;
689        }
690
691
692        /**
693         * Sets the post logout redirection URIs. Corresponds to the
694         * {@code post_logout_redirect_uris} client metadata field.
695         *
696         * @param logoutURIs The logout redirection URIs, {@code null} if not
697         *                   specified.
698         */
699        public void setPostLogoutRedirectionURIs(final Set<URI> logoutURIs) {
700
701                postLogoutRedirectURIs = logoutURIs;
702        }
703        
704        
705        /**
706         * Applies the client metadata defaults where no values have been
707         * specified.
708         * 
709         * <ul>
710         *     <li>The response types default to {@code ["code"]}.
711         *     <li>The grant types default to {@code "authorization_code".}
712         *     <li>The client authentication method defaults to
713         *         "client_secret_basic".
714         *     <li>The application type defaults to
715         *         {@link ApplicationType#WEB}.
716         *     <li>The ID token JWS algorithm defaults to "RS256".
717         * </ul>
718         */
719        @Override
720        public void applyDefaults() {
721                
722                super.applyDefaults();
723
724                if (applicationType == null) {
725                        applicationType = ApplicationType.WEB;
726                }
727                
728                if (idTokenJWSAlg == null) {
729                        idTokenJWSAlg = JWSAlgorithm.RS256;
730                }
731        }
732
733
734        @Override
735        public JSONObject toJSONObject() {
736
737                JSONObject o = super.toJSONObject(false);
738
739                o.putAll(getCustomFields());
740
741                if (applicationType != null)
742                        o.put("application_type", applicationType.toString());
743
744                if (subjectType != null)
745                        o.put("subject_type", subjectType.toString());
746
747
748                if (sectorIDURI != null)
749                        o.put("sector_identifier_uri", sectorIDURI.toString());
750                
751                
752                if (requestObjectURIs != null) {
753                        
754                        JSONArray uriList = new JSONArray();
755                        
756                        for (URI uri: requestObjectURIs)
757                                uriList.add(uri.toString());
758                        
759                        o.put("request_uris", uriList);
760                }
761
762
763                if (requestObjectJWSAlg != null)
764                        o.put("request_object_signing_alg", requestObjectJWSAlg.getName());
765
766                if (requestObjectJWEAlg != null)
767                        o.put("request_object_encryption_alg", requestObjectJWEAlg.getName());
768
769                if (requestObjectJWEEnc != null)
770                        o.put("request_object_encryption_enc", requestObjectJWEEnc.getName());
771
772
773                if (idTokenJWSAlg != null)
774                        o.put("id_token_signed_response_alg", idTokenJWSAlg.getName());
775
776
777                if (idTokenJWEAlg != null)
778                        o.put("id_token_encrypted_response_alg", idTokenJWEAlg.getName());
779
780
781                if (idTokenJWEEnc != null)
782                        o.put("id_token_encrypted_response_enc", idTokenJWEEnc.getName());
783
784
785                if (userInfoJWSAlg != null)
786                        o.put("userinfo_signed_response_alg", userInfoJWSAlg.getName());
787
788
789                if (userInfoJWEAlg != null)
790                        o.put("userinfo_encrypted_response_alg", userInfoJWEAlg.getName());
791
792
793                if (userInfoJWEEnc != null)
794                        o.put("userinfo_encrypted_response_enc", userInfoJWEEnc.getName());
795
796
797                if (defaultMaxAge > 0)
798                        o.put("default_max_age", defaultMaxAge);
799
800
801                if (requiresAuthTime())
802                        o.put("require_auth_time", requiresAuthTime);
803
804
805                if (defaultACRs != null) {
806
807                        JSONArray acrList = new JSONArray();
808
809                        for (ACR acr: defaultACRs)
810                                acrList.add(acr);
811
812                        o.put("default_acr_values", acrList);
813                }
814
815
816                if (initiateLoginURI != null)
817                        o.put("initiate_login_uri", initiateLoginURI.toString());
818
819
820                if (postLogoutRedirectURIs != null) {
821
822                        JSONArray uriList = new JSONArray();
823
824                        for (URI uri: postLogoutRedirectURIs)
825                                uriList.add(uri.toString());
826
827                        o.put("post_logout_redirect_uris", uriList);
828                }
829
830                return o;
831        }
832
833
834        /**
835         * Parses an OpenID Connect client metadata instance from the specified
836         * JSON object.
837         *
838         * @param jsonObject The JSON object to parse. Must not be 
839         *                   {@code null}.
840         *
841         * @return The OpenID Connect client metadata.
842         *
843         * @throws ParseException If the JSON object couldn't be parsed to an
844         *                        OpenID Connect client metadata instance.
845         */
846        public static OIDCClientMetadata parse(final JSONObject jsonObject)
847                throws ParseException {
848
849                ClientMetadata baseMetadata = ClientMetadata.parse(jsonObject);
850                
851                OIDCClientMetadata metadata = new OIDCClientMetadata(baseMetadata);
852
853                // Parse the OIDC-specific fields from the custom OAuth 2.0 dyn
854                // reg fields
855
856                JSONObject oidcFields = baseMetadata.getCustomFields();
857
858                if (jsonObject.containsKey("application_type")) {
859                        metadata.setApplicationType(JSONObjectUtils.getEnum(jsonObject, "application_type", ApplicationType.class));
860                        oidcFields.remove("application_type");
861                }
862                
863                if (jsonObject.containsKey("subject_type")) {
864                        metadata.setSubjectType(JSONObjectUtils.getEnum(jsonObject, "subject_type", SubjectType.class));
865                        oidcFields.remove("subject_type");
866                }
867
868                if (jsonObject.containsKey("sector_identifier_uri")) {
869                        metadata.setSectorIDURI(JSONObjectUtils.getURI(jsonObject, "sector_identifier_uri"));
870                        oidcFields.remove("sector_identifier_uri");
871                }
872
873                if (jsonObject.containsKey("request_uris")) {
874                        
875                        Set<URI> requestURIs = new LinkedHashSet<>();
876                        
877                        for (String uriString: JSONObjectUtils.getStringArray(jsonObject, "request_uris")) {
878                                
879                                try {
880                                        requestURIs.add(new URI(uriString));
881                                        
882                                } catch (URISyntaxException e) {
883                                        
884                                        throw new ParseException("Invalid \"request_uris\" parameter");
885                                }
886                        }
887                        
888                        metadata.setRequestObjectURIs(requestURIs);
889                        oidcFields.remove("request_uris");
890                }
891                
892                if (jsonObject.containsKey("request_object_signing_alg")) {
893                        metadata.setRequestObjectJWSAlg(new JWSAlgorithm(
894                                JSONObjectUtils.getString(jsonObject, "request_object_signing_alg")));
895
896                        oidcFields.remove("request_object_signing_alg");
897                }
898
899                if (jsonObject.containsKey("request_object_encryption_alg")) {
900                        metadata.setRequestObjectJWEAlg(new JWEAlgorithm(
901                                JSONObjectUtils.getString(jsonObject, "request_object_encryption_alg")));
902
903                        oidcFields.remove("request_object_encryption_alg");
904                }
905
906                if (jsonObject.containsKey("request_object_encryption_enc")) {
907                        metadata.setRequestObjectJWEEnc(EncryptionMethod.parse(
908                                JSONObjectUtils.getString(jsonObject, "request_object_encryption_enc")));
909
910                        oidcFields.remove("request_object_encryption_enc");
911                }
912
913                if (jsonObject.containsKey("id_token_signed_response_alg")) {
914                        metadata.setIDTokenJWSAlg(new JWSAlgorithm(
915                                JSONObjectUtils.getString(jsonObject, "id_token_signed_response_alg")));
916
917                        oidcFields.remove("id_token_signed_response_alg");
918                }
919
920                if (jsonObject.containsKey("id_token_encrypted_response_alg")) {
921                        metadata.setIDTokenJWEAlg(new JWEAlgorithm(
922                                JSONObjectUtils.getString(jsonObject, "id_token_encrypted_response_alg")));
923
924                        oidcFields.remove("id_token_encrypted_response_alg");
925                }
926
927                if (jsonObject.containsKey("id_token_encrypted_response_enc")) {
928                        metadata.setIDTokenJWEEnc(EncryptionMethod.parse(
929                                JSONObjectUtils.getString(jsonObject, "id_token_encrypted_response_enc")));
930
931                        oidcFields.remove("id_token_encrypted_response_enc");
932                }
933
934                if (jsonObject.containsKey("userinfo_signed_response_alg")) {
935                        metadata.setUserInfoJWSAlg(new JWSAlgorithm(
936                                JSONObjectUtils.getString(jsonObject, "userinfo_signed_response_alg")));
937
938                        oidcFields.remove("userinfo_signed_response_alg");
939                }
940
941                if (jsonObject.containsKey("userinfo_encrypted_response_alg")) {
942                        metadata.setUserInfoJWEAlg(new JWEAlgorithm(
943                                JSONObjectUtils.getString(jsonObject, "userinfo_encrypted_response_alg")));
944
945                        oidcFields.remove("userinfo_encrypted_response_alg");
946                }
947
948                if (jsonObject.containsKey("userinfo_encrypted_response_enc")) {
949                        metadata.setUserInfoJWEEnc(EncryptionMethod.parse(
950                                JSONObjectUtils.getString(jsonObject, "userinfo_encrypted_response_enc")));
951
952                        oidcFields.remove("userinfo_encrypted_response_enc");
953                }
954
955                if (jsonObject.containsKey("default_max_age")) {
956                        metadata.setDefaultMaxAge(JSONObjectUtils.getInt(jsonObject, "default_max_age"));
957                        oidcFields.remove("default_max_age");
958                }
959
960                if (jsonObject.containsKey("require_auth_time")) {
961                        metadata.requiresAuthTime(JSONObjectUtils.getBoolean(jsonObject, "require_auth_time"));
962                        oidcFields.remove("require_auth_time");
963                }
964
965                if (jsonObject.containsKey("default_acr_values")) {
966
967                        List<ACR> acrValues = new LinkedList<>();
968
969                        for (String acrString: JSONObjectUtils.getStringArray(jsonObject, "default_acr_values"))
970                                acrValues.add(new ACR(acrString));
971
972                        metadata.setDefaultACRs(acrValues);
973
974                        oidcFields.remove("default_acr_values");
975                }
976
977                if (jsonObject.containsKey("initiate_login_uri")) {
978                        metadata.setInitiateLoginURI(JSONObjectUtils.getURI(jsonObject, "initiate_login_uri"));
979                        oidcFields.remove("initiate_login_uri");
980                }
981
982                if (jsonObject.containsKey("post_logout_redirect_uris")) {
983
984                        Set<URI> logoutURIs = new LinkedHashSet<>();
985
986                        for (String uriString: JSONObjectUtils.getStringArray(jsonObject, "post_logout_redirect_uris")) {
987
988                                try {
989                                        logoutURIs.add(new URI(uriString));
990
991                                } catch (URISyntaxException e) {
992
993                                        throw new ParseException("Invalid \"post_logout_redirect_uris\" parameter");
994                                }
995                        }
996
997                        metadata.setPostLogoutRedirectionURIs(logoutURIs);
998                        oidcFields.remove("post_logout_redirect_uris");
999                }
1000
1001                // The remaining fields are custom
1002                metadata.setCustomFields(oidcFields);
1003
1004                return metadata;
1005        }
1006}