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 OpenID Connect client metadata parameter names.
220         *
221         * @return The registered OpenID Connect parameter names, as an
222         *         unmodifiable set.
223         */
224        public static Set<String> getRegisteredParameterNames() {
225
226                return REGISTERED_PARAMETER_NAMES;
227        }
228
229
230        /**
231         * Gets the client application type. Corresponds to the
232         * {@code application_type} client metadata field.
233         *
234         * @return The client application type, {@code null} if not specified.
235         */
236        public ApplicationType getApplicationType() {
237
238                return applicationType;
239        }
240
241
242        /**
243         * Sets the client application type. Corresponds to the
244         * {@code application_type} client metadata field.
245         *
246         * @param applicationType The client application type, {@code null} if
247         *                        not specified.
248         */
249        public void setApplicationType(final ApplicationType applicationType) {
250
251                this.applicationType = applicationType;
252        }
253
254
255        /**
256         * Gets the subject identifier type for responses to this client. 
257         * Corresponds to the {@code subject_type} client metadata field.
258         *
259         * @return The subject identifier type, {@code null} if not specified.
260         */
261        public SubjectType getSubjectType() {
262
263                return subjectType;
264        }
265
266
267        /**
268         * Sets the subject identifier type for responses to this client. 
269         * Corresponds to the {@code subject_type} client metadata field.
270         *
271         * @param subjectType The subject identifier type, {@code null} if not 
272         *                    specified.
273         */
274        public void setSubjectType(final SubjectType subjectType) {
275
276                this.subjectType = subjectType;
277        }
278
279
280        /**
281         * Gets the sector identifier URI. Corresponds to the 
282         * {@code sector_identifier_uri} client metadata field.
283         *
284         * @return The sector identifier URI, {@code null} if not specified.
285         */
286        public URI getSectorIDURI() {
287
288                return sectorIDURI;
289        }
290
291
292        /**
293         * Sets the sector identifier URI. Corresponds to the 
294         * {@code sector_identifier_uri} client metadata field.
295         *
296         * @param sectorIDURI The sector identifier URI, {@code null} if not 
297         *                    specified.
298         */
299        public void setSectorIDURI(final URI sectorIDURI) {
300
301                this.sectorIDURI = sectorIDURI;
302        }
303        
304        
305        /**
306         * Gets the pre-registered OpenID Connect request object URIs.
307         * Corresponds to the {@code request_uris} client metadata field.
308         * 
309         * @return The request object URIs, {@code null} if not specified.
310         */
311        public Set<URI> getRequestObjectURIs() {
312                
313                return requestObjectURIs;
314        }
315        
316        
317        /**
318         * Sets the pre-registered OpenID Connect request object URIs.
319         * Corresponds to the {@code request_uris} client metadata field.
320         *
321         * @param requestObjectURIs The request object URIs, {@code null} if
322         *                          not specified.
323         */
324        public void setRequestObjectURIs(final Set<URI> requestObjectURIs) {
325
326                this.requestObjectURIs = requestObjectURIs;
327        }
328
329
330        /**
331         * Gets the JSON Web Signature (JWS) algorithm required for the OpenID 
332         * Connect request objects sent by this client. Corresponds to the 
333         * {@code request_object_signing_alg} client metadata field.
334         *
335         * @return The JWS algorithm, {@code null} if not specified.
336         */
337        public JWSAlgorithm getRequestObjectJWSAlg() {
338
339                return requestObjectJWSAlg;
340        }
341
342
343        /**
344         * Sets the JSON Web Signature (JWS) algorithm required for the OpenID 
345         * Connect request objects sent by this client. Corresponds to the 
346         * {@code request_object_signing_alg} client metadata field.
347         *
348         * @param requestObjectJWSAlg The JWS algorithm, {@code null} if not 
349         *                            specified.
350         */
351        public void setRequestObjectJWSAlg(final JWSAlgorithm requestObjectJWSAlg) {
352
353                this.requestObjectJWSAlg = requestObjectJWSAlg;
354        }
355
356
357        /**
358         * Gets the JSON Web Encryption (JWE) algorithm required for the OpenID
359         * Connect request objects sent by this client. Corresponds to the
360         * {@code request_object_encryption_alg} client metadata field.
361         *
362         * @return The JWE algorithm, {@code null} if not specified.
363         */
364        public JWEAlgorithm getRequestObjectJWEAlg() {
365
366                return requestObjectJWEAlg;
367        }
368
369
370        /**
371         * Sets the JSON Web Encryption (JWE) algorithm required for the OpenID
372         * Connect request objects sent by this client. Corresponds to the
373         * {@code request_object_encryption_alg} client metadata field.
374         *
375         * @param requestObjectJWEAlg The JWE algorithm, {@code null} if not
376         *                            specified.
377         */
378        public void setRequestObjectJWEAlg(final JWEAlgorithm requestObjectJWEAlg) {
379
380                this.requestObjectJWEAlg = requestObjectJWEAlg;
381        }
382
383
384        /**
385         * Gets the JSON Web Encryption (JWE) method required for the OpenID
386         * Connect request objects sent by this client. Corresponds to the
387         * {@code request_object_encryption_enc} client metadata field.
388         *
389         * @return The JWE method, {@code null} if not specified.
390         */
391        public EncryptionMethod getRequestObjectJWEEnc() {
392
393                return requestObjectJWEEnc;
394        }
395
396
397        /**
398         * Sets the JSON Web Encryption (JWE) method required for the OpenID
399         * Connect request objects sent by this client. Corresponds to the
400         * {@code request_object_encryption_enc} client metadata field.
401         *
402         * @param requestObjectJWEEnc The JWE method, {@code null} if not
403         *                            specified.
404         */
405        public void setRequestObjectJWEEnc(final EncryptionMethod requestObjectJWEEnc) {
406
407                this.requestObjectJWEEnc = requestObjectJWEEnc;
408        }
409
410
411        /**
412         * Gets the JSON Web Signature (JWS) algorithm required for the ID 
413         * Tokens issued to this client. Corresponds to the 
414         * {@code id_token_signed_response_alg} client metadata field.
415         *
416         * @return The JWS algorithm, {@code null} if not specified.
417         */
418        public JWSAlgorithm getIDTokenJWSAlg() {
419
420                return idTokenJWSAlg;
421        }
422
423
424        /**
425         * Sets the JSON Web Signature (JWS) algorithm required for the ID 
426         * Tokens issued to this client. Corresponds to the 
427         * {@code id_token_signed_response_alg} client metadata field.
428         *
429         * @param idTokenJWSAlg The JWS algorithm, {@code null} if not 
430         *                      specified.
431         */
432        public void setIDTokenJWSAlg(final JWSAlgorithm idTokenJWSAlg) {
433
434                this.idTokenJWSAlg = idTokenJWSAlg;
435        }
436
437
438        /**
439         * Gets the JSON Web Encryption (JWE) algorithm required for the ID 
440         * Tokens issued to this client. Corresponds to the 
441         * {@code id_token_encrypted_response_alg} client metadata field.
442         *
443         * @return The JWE algorithm, {@code null} if not specified.
444         */
445        public JWEAlgorithm getIDTokenJWEAlg() {
446
447                return idTokenJWEAlg;
448        }
449
450
451        /**
452         * Sets the JSON Web Encryption (JWE) algorithm required for the ID 
453         * Tokens issued to this client. Corresponds to the 
454         * {@code id_token_encrypted_response_alg} client metadata field.
455         *
456         * @param idTokenJWEAlg The JWE algorithm, {@code null} if not 
457         *                      specified.
458         */
459        public void setIDTokenJWEAlg(final JWEAlgorithm idTokenJWEAlg) {
460
461                this.idTokenJWEAlg = idTokenJWEAlg;
462        }
463
464
465        /**
466         * Gets the JSON Web Encryption (JWE) method required for the ID Tokens
467         * issued to this client. Corresponds to the 
468         * {@code id_token_encrypted_response_enc} client metadata field.
469         *
470         * @return The JWE method, {@code null} if not specified.
471         */
472        public EncryptionMethod getIDTokenJWEEnc() {
473
474                return idTokenJWEEnc;
475        }
476
477
478        /**
479         * Sets the JSON Web Encryption (JWE) method required for the ID Tokens
480         * issued to this client. Corresponds to the 
481         * {@code id_token_encrypted_response_enc} client metadata field.
482         *
483         * @param idTokenJWEEnc The JWE method, {@code null} if not specified.
484         */
485        public void setIDTokenJWEEnc(final EncryptionMethod idTokenJWEEnc) {
486
487                this.idTokenJWEEnc = idTokenJWEEnc;
488        }
489
490
491        /**
492         * Gets the JSON Web Signature (JWS) algorithm required for the 
493         * UserInfo responses to this client. Corresponds to the 
494         * {@code userinfo_signed_response_alg} client metadata field.
495         *
496         * @return The JWS algorithm, {@code null} if not specified.
497         */
498        public JWSAlgorithm getUserInfoJWSAlg() {
499
500                return userInfoJWSAlg;
501        }
502
503
504        /**
505         * Sets the JSON Web Signature (JWS) algorithm required for the 
506         * UserInfo responses to this client. Corresponds to the
507         * {@code userinfo_signed_response_alg} client metadata field.
508         *
509         * @param userInfoJWSAlg The JWS algorithm, {@code null} if not 
510         *                       specified.
511         */
512        public void setUserInfoJWSAlg(final JWSAlgorithm userInfoJWSAlg) {
513
514                this.userInfoJWSAlg = userInfoJWSAlg;
515        }
516
517
518        /**
519         * Gets the JSON Web Encryption (JWE) algorithm required for the 
520         * UserInfo responses to this client. Corresponds to the 
521         * {@code userinfo_encrypted_response_alg} client metadata field.
522         *
523         * @return The JWE algorithm, {@code null} if not specified.
524         */
525        public JWEAlgorithm getUserInfoJWEAlg() {
526
527                return userInfoJWEAlg;
528        }
529
530
531        /**
532         * Sets the JSON Web Encryption (JWE) algorithm required for the 
533         * UserInfo responses to this client. Corresponds to the 
534         * {@code userinfo_encrypted_response_alg} client metadata field.
535         *
536         * @param userInfoJWEAlg The JWE algorithm, {@code null} if not
537         *                       specified.
538         */
539        public void setUserInfoJWEAlg(final JWEAlgorithm userInfoJWEAlg) {
540
541                this.userInfoJWEAlg = userInfoJWEAlg;
542        }
543
544
545        /**
546         * Gets the JSON Web Encryption (JWE) method required for the UserInfo
547         * responses to this client. Corresponds to the 
548         * {@code userinfo_encrypted_response_enc} client metadata field.
549         *
550         * @return The JWE method, {@code null} if not specified.
551         */
552        public EncryptionMethod getUserInfoJWEEnc() {
553
554                return userInfoJWEEnc;
555        }
556
557
558        /**
559         * Sets the JSON Web Encryption (JWE) method required for the UserInfo
560         * responses to this client. Corresponds to the 
561         * {@code userinfo_encrypted_response_enc} client metadata field.
562         *
563         * @param userInfoJWEEnc The JWE method, {@code null} if not specified.
564         */
565        public void setUserInfoJWEEnc(final EncryptionMethod userInfoJWEEnc) {
566
567                this.userInfoJWEEnc = userInfoJWEEnc;
568        }
569
570
571        /**
572         * Gets the default maximum authentication age. Corresponds to the 
573         * {@code default_max_age} client metadata field.
574         *
575         * @return The default max authentication age, in seconds. If not
576         *         specified 0.
577         */
578        public int getDefaultMaxAge() {
579
580                return defaultMaxAge;
581        }
582
583
584        /**
585         * Sets the default maximum authentication age. Corresponds to the 
586         * {@code default_max_age} client metadata field.
587         *
588         * @param defaultMaxAge The default max authentication age, in seconds.
589         *                      If not specified 0.
590         */
591        public void setDefaultMaxAge(final int defaultMaxAge) {
592
593                this.defaultMaxAge = defaultMaxAge;
594        }
595
596
597        /**
598         * Gets the default requirement for the {@code auth_time} claim in the
599         * ID Token. Corresponds to the {@code require_auth_time} client 
600         * metadata field.
601         *
602         * @return If {@code true} the {@code auth_Time} claim in the ID Token 
603         *         is required by default.
604         */
605        public boolean requiresAuthTime() {
606
607                return requiresAuthTime;
608        }
609
610
611        /**
612         * Sets the default requirement for the {@code auth_time} claim in the
613         * ID Token. Corresponds to the {@code require_auth_time} client 
614         * metadata field.
615         *
616         * @param requiresAuthTime If {@code true} the {@code auth_Time} claim 
617         *                         in the ID Token is required by default.
618         */
619        public void requiresAuthTime(final boolean requiresAuthTime) {
620
621                this.requiresAuthTime = requiresAuthTime;
622        }
623
624
625        /**
626         * Gets the default Authentication Context Class Reference (ACR) 
627         * values. Corresponds to the {@code default_acr_values} client 
628         * metadata field.
629         *
630         * @return The default ACR values, by order of preference, 
631         *         {@code null} if not specified.
632         */
633        public List<ACR> getDefaultACRs() {
634
635                return defaultACRs;
636        }
637
638
639        /**
640         * Sets the default Authentication Context Class Reference (ACR)
641         * values. Corresponds to the {@code default_acr_values} client 
642         * metadata field.
643         *
644         * @param defaultACRs The default ACRs, by order of preference, 
645         *                    {@code null} if not specified.
646         */
647        public void setDefaultACRs(final List<ACR> defaultACRs) {
648
649                this.defaultACRs = defaultACRs;
650        }
651
652
653        /**
654         * Gets the HTTPS URI that the authorisation server can call to
655         * initiate a login at the client. Corresponds to the 
656         * {@code initiate_login_uri} client metadata field.
657         *
658         * @return The login URI, {@code null} if not specified.
659         */
660        public URI getInitiateLoginURI() {
661
662                return initiateLoginURI;
663        }
664
665
666        /**
667         * Sets the HTTPS URI that the authorisation server can call to
668         * initiate a login at the client. Corresponds to the 
669         * {@code initiate_login_uri} client metadata field.
670         *
671         * @param loginURI The login URI, {@code null} if not specified.
672         */
673        public void setInitiateLoginURI(final URI loginURI) {
674
675                this.initiateLoginURI = loginURI;
676        }
677
678
679        /**
680         * Gets the post logout redirection URIs. Corresponds to the
681         * {@code post_logout_redirect_uris} client metadata field.
682         *
683         * @return The logout redirection URIs, {@code null} if not specified.
684         */
685        public Set<URI> getPostLogoutRedirectionURIs() {
686
687                return postLogoutRedirectURIs;
688        }
689
690
691        /**
692         * Sets the post logout redirection URIs. Corresponds to the
693         * {@code post_logout_redirect_uris} client metadata field.
694         *
695         * @param logoutURIs The logout redirection URIs, {@code null} if not
696         *                   specified.
697         */
698        public void setPostLogoutRedirectionURIs(final Set<URI> logoutURIs) {
699
700                postLogoutRedirectURIs = logoutURIs;
701        }
702        
703        
704        /**
705         * Applies the client metadata defaults where no values have been
706         * specified.
707         * 
708         * <ul>
709         *     <li>The response types default to {@code ["code"]}.
710         *     <li>The grant types default to {@code "authorization_code".}
711         *     <li>The client authentication method defaults to
712         *         "client_secret_basic".
713         *     <li>The application type defaults to
714         *         {@link ApplicationType#WEB}.
715         *     <li>The ID token JWS algorithm defaults to "RS256".
716         * </ul>
717         */
718        @Override
719        public void applyDefaults() {
720                
721                super.applyDefaults();
722
723                if (applicationType == null) {
724                        applicationType = ApplicationType.WEB;
725                }
726                
727                if (idTokenJWSAlg == null) {
728                        idTokenJWSAlg = JWSAlgorithm.RS256;
729                }
730        }
731
732
733        @Override
734        public JSONObject toJSONObject() {
735
736                JSONObject o = super.toJSONObject(false);
737
738                o.putAll(getCustomFields());
739
740                if (applicationType != null)
741                        o.put("application_type", applicationType.toString());
742
743                if (subjectType != null)
744                        o.put("subject_type", subjectType.toString());
745
746
747                if (sectorIDURI != null)
748                        o.put("sector_identifier_uri", sectorIDURI.toString());
749                
750                
751                if (requestObjectURIs != null) {
752                        
753                        JSONArray uriList = new JSONArray();
754                        
755                        for (URI uri: requestObjectURIs)
756                                uriList.add(uri.toString());
757                        
758                        o.put("request_uris", uriList);
759                }
760
761
762                if (requestObjectJWSAlg != null)
763                        o.put("request_object_signing_alg", requestObjectJWSAlg.getName());
764
765                if (requestObjectJWEAlg != null)
766                        o.put("request_object_encryption_alg", requestObjectJWEAlg.getName());
767
768                if (requestObjectJWEEnc != null)
769                        o.put("request_object_encryption_enc", requestObjectJWEEnc.getName());
770
771
772                if (idTokenJWSAlg != null)
773                        o.put("id_token_signed_response_alg", idTokenJWSAlg.getName());
774
775
776                if (idTokenJWEAlg != null)
777                        o.put("id_token_encrypted_response_alg", idTokenJWEAlg.getName());
778
779
780                if (idTokenJWEEnc != null)
781                        o.put("id_token_encrypted_response_enc", idTokenJWEEnc.getName());
782
783
784                if (userInfoJWSAlg != null)
785                        o.put("userinfo_signed_response_alg", userInfoJWSAlg.getName());
786
787
788                if (userInfoJWEAlg != null)
789                        o.put("userinfo_encrypted_response_alg", userInfoJWEAlg.getName());
790
791
792                if (userInfoJWEEnc != null)
793                        o.put("userinfo_encrypted_response_enc", userInfoJWEEnc.getName());
794
795
796                if (defaultMaxAge > 0)
797                        o.put("default_max_age", defaultMaxAge);
798
799
800                if (requiresAuthTime())
801                        o.put("require_auth_time", requiresAuthTime);
802
803
804                if (defaultACRs != null) {
805
806                        JSONArray acrList = new JSONArray();
807
808                        for (ACR acr: defaultACRs)
809                                acrList.add(acr);
810
811                        o.put("default_acr_values", acrList);
812                }
813
814
815                if (initiateLoginURI != null)
816                        o.put("initiate_login_uri", initiateLoginURI.toString());
817
818
819                if (postLogoutRedirectURIs != null) {
820
821                        JSONArray uriList = new JSONArray();
822
823                        for (URI uri: postLogoutRedirectURIs)
824                                uriList.add(uri.toString());
825
826                        o.put("post_logout_redirect_uris", uriList);
827                }
828
829                return o;
830        }
831
832
833        /**
834         * Parses an OpenID Connect client metadata instance from the specified
835         * JSON object.
836         *
837         * @param jsonObject The JSON object to parse. Must not be 
838         *                   {@code null}.
839         *
840         * @return The OpenID Connect client metadata.
841         *
842         * @throws ParseException If the JSON object couldn't be parsed to an
843         *                        OpenID Connect client metadata instance.
844         */
845        public static OIDCClientMetadata parse(final JSONObject jsonObject)
846                throws ParseException {
847
848                ClientMetadata baseMetadata = ClientMetadata.parse(jsonObject);
849                
850                OIDCClientMetadata metadata = new OIDCClientMetadata(baseMetadata);
851
852                // Parse the OIDC-specific fields from the custom OAuth 2.0 dyn
853                // reg fields
854
855                JSONObject oidcFields = baseMetadata.getCustomFields();
856
857                if (jsonObject.containsKey("application_type")) {
858                        metadata.setApplicationType(JSONObjectUtils.getEnum(jsonObject, "application_type", ApplicationType.class));
859                        oidcFields.remove("application_type");
860                }
861                
862                if (jsonObject.containsKey("subject_type")) {
863                        metadata.setSubjectType(JSONObjectUtils.getEnum(jsonObject, "subject_type", SubjectType.class));
864                        oidcFields.remove("subject_type");
865                }
866
867                if (jsonObject.containsKey("sector_identifier_uri")) {
868                        metadata.setSectorIDURI(JSONObjectUtils.getURI(jsonObject, "sector_identifier_uri"));
869                        oidcFields.remove("sector_identifier_uri");
870                }
871
872                if (jsonObject.containsKey("request_uris")) {
873                        
874                        Set<URI> requestURIs = new LinkedHashSet<>();
875                        
876                        for (String uriString: JSONObjectUtils.getStringArray(jsonObject, "request_uris")) {
877                                
878                                try {
879                                        requestURIs.add(new URI(uriString));
880                                        
881                                } catch (URISyntaxException e) {
882                                        
883                                        throw new ParseException("Invalid \"request_uris\" parameter");
884                                }
885                        }
886                        
887                        metadata.setRequestObjectURIs(requestURIs);
888                        oidcFields.remove("request_uris");
889                }
890                
891                if (jsonObject.containsKey("request_object_signing_alg")) {
892                        metadata.setRequestObjectJWSAlg(new JWSAlgorithm(
893                                JSONObjectUtils.getString(jsonObject, "request_object_signing_alg")));
894
895                        oidcFields.remove("request_object_signing_alg");
896                }
897
898                if (jsonObject.containsKey("request_object_encryption_alg")) {
899                        metadata.setRequestObjectJWEAlg(new JWEAlgorithm(
900                                JSONObjectUtils.getString(jsonObject, "request_object_encryption_alg")));
901
902                        oidcFields.remove("request_object_encryption_alg");
903                }
904
905                if (jsonObject.containsKey("request_object_encryption_enc")) {
906                        metadata.setRequestObjectJWEEnc(EncryptionMethod.parse(
907                                JSONObjectUtils.getString(jsonObject, "request_object_encryption_enc")));
908
909                        oidcFields.remove("request_object_encryption_enc");
910                }
911
912                if (jsonObject.containsKey("id_token_signed_response_alg")) {
913                        metadata.setIDTokenJWSAlg(new JWSAlgorithm(
914                                JSONObjectUtils.getString(jsonObject, "id_token_signed_response_alg")));
915
916                        oidcFields.remove("id_token_signed_response_alg");
917                }
918
919                if (jsonObject.containsKey("id_token_encrypted_response_alg")) {
920                        metadata.setIDTokenJWEAlg(new JWEAlgorithm(
921                                JSONObjectUtils.getString(jsonObject, "id_token_encrypted_response_alg")));
922
923                        oidcFields.remove("id_token_encrypted_response_alg");
924                }
925
926                if (jsonObject.containsKey("id_token_encrypted_response_enc")) {
927                        metadata.setIDTokenJWEEnc(EncryptionMethod.parse(
928                                JSONObjectUtils.getString(jsonObject, "id_token_encrypted_response_enc")));
929
930                        oidcFields.remove("id_token_encrypted_response_enc");
931                }
932
933                if (jsonObject.containsKey("userinfo_signed_response_alg")) {
934                        metadata.setUserInfoJWSAlg(new JWSAlgorithm(
935                                JSONObjectUtils.getString(jsonObject, "userinfo_signed_response_alg")));
936
937                        oidcFields.remove("userinfo_signed_response_alg");
938                }
939
940                if (jsonObject.containsKey("userinfo_encrypted_response_alg")) {
941                        metadata.setUserInfoJWEAlg(new JWEAlgorithm(
942                                JSONObjectUtils.getString(jsonObject, "userinfo_encrypted_response_alg")));
943
944                        oidcFields.remove("userinfo_encrypted_response_alg");
945                }
946
947                if (jsonObject.containsKey("userinfo_encrypted_response_enc")) {
948                        metadata.setUserInfoJWEEnc(EncryptionMethod.parse(
949                                JSONObjectUtils.getString(jsonObject, "userinfo_encrypted_response_enc")));
950
951                        oidcFields.remove("userinfo_encrypted_response_enc");
952                }
953
954                if (jsonObject.containsKey("default_max_age")) {
955                        metadata.setDefaultMaxAge(JSONObjectUtils.getInt(jsonObject, "default_max_age"));
956                        oidcFields.remove("default_max_age");
957                }
958
959                if (jsonObject.containsKey("require_auth_time")) {
960                        metadata.requiresAuthTime(JSONObjectUtils.getBoolean(jsonObject, "require_auth_time"));
961                        oidcFields.remove("require_auth_time");
962                }
963
964                if (jsonObject.containsKey("default_acr_values")) {
965
966                        List<ACR> acrValues = new LinkedList<>();
967
968                        for (String acrString: JSONObjectUtils.getStringArray(jsonObject, "default_acr_values"))
969                                acrValues.add(new ACR(acrString));
970
971                        metadata.setDefaultACRs(acrValues);
972
973                        oidcFields.remove("default_acr_values");
974                }
975
976                if (jsonObject.containsKey("initiate_login_uri")) {
977                        metadata.setInitiateLoginURI(JSONObjectUtils.getURI(jsonObject, "initiate_login_uri"));
978                        oidcFields.remove("initiate_login_uri");
979                }
980
981                if (jsonObject.containsKey("post_logout_redirect_uris")) {
982
983                        Set<URI> logoutURIs = new LinkedHashSet<>();
984
985                        for (String uriString: JSONObjectUtils.getStringArray(jsonObject, "post_logout_redirect_uris")) {
986
987                                try {
988                                        logoutURIs.add(new URI(uriString));
989
990                                } catch (URISyntaxException e) {
991
992                                        throw new ParseException("Invalid \"post_logout_redirect_uris\" parameter");
993                                }
994                        }
995
996                        metadata.setPostLogoutRedirectionURIs(logoutURIs);
997                        oidcFields.remove("post_logout_redirect_uris");
998                }
999
1000                // The remaining fields are custom
1001                metadata.setCustomFields(oidcFields);
1002
1003                return metadata;
1004        }
1005}