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