001/*
002 * oauth2-oidc-sdk
003 *
004 * Copyright 2012-2016, Connect2id Ltd and contributors.
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
007 * this file except in compliance with the License. You may obtain a copy of the
008 * License at
009 *
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software distributed
013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the
015 * specific language governing permissions and limitations under the License.
016 */
017
018package com.nimbusds.openid.connect.sdk;
019
020
021import com.nimbusds.jwt.JWT;
022import com.nimbusds.jwt.JWTClaimsSet;
023import com.nimbusds.jwt.JWTParser;
024import com.nimbusds.langtag.LangTag;
025import com.nimbusds.langtag.LangTagException;
026import com.nimbusds.langtag.LangTagUtils;
027import com.nimbusds.oauth2.sdk.*;
028import com.nimbusds.oauth2.sdk.dpop.JWKThumbprintConfirmation;
029import com.nimbusds.oauth2.sdk.http.HTTPRequest;
030import com.nimbusds.oauth2.sdk.id.ClientID;
031import com.nimbusds.oauth2.sdk.id.State;
032import com.nimbusds.oauth2.sdk.pkce.CodeChallenge;
033import com.nimbusds.oauth2.sdk.pkce.CodeChallengeMethod;
034import com.nimbusds.oauth2.sdk.pkce.CodeVerifier;
035import com.nimbusds.oauth2.sdk.rar.AuthorizationDetail;
036import com.nimbusds.oauth2.sdk.util.*;
037import com.nimbusds.openid.connect.sdk.claims.ACR;
038import com.nimbusds.openid.connect.sdk.federation.trust.TrustChain;
039import net.jcip.annotations.Immutable;
040
041import java.net.URI;
042import java.util.*;
043
044
045/**
046 * OpenID Connect authentication request. Intended to authenticate an end-user
047 * and request the end-user's authorisation to release information to the
048 * client. Supports custom request parameters.
049 *
050 * <p>Example HTTP request (code flow):
051 *
052 * <pre>
053 * https://server.example.com/op/authorize?
054 * response_type=code%20id_token
055 * &amp;client_id=s6BhdRkqt3
056 * &amp;redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
057 * &amp;scope=openid
058 * &amp;nonce=n-0S6_WzA2Mj
059 * &amp;state=af0ifjsldkj
060 * </pre>
061 *
062 * <p>Related specifications:
063 *
064 * <ul>
065 *     <li>OpenID Connect Core 1.0, section 3.1.2.1.
066 *     <li>Proof Key for Code Exchange by OAuth Public Clients (RFC 7636).
067 *     <li>OAuth 2.0 Rich Authorization Requests (RFC 9396).
068 *     <li>Resource Indicators for OAuth 2.0 (RFC 8707)
069 *     <li>OAuth 2.0 Incremental Authorization
070 *         (draft-ietf-oauth-incremental-authz-04)
071 *     <li>The OAuth 2.0 Authorization Framework: JWT Secured Authorization
072 *         Request (JAR) (RFC 9101)
073 *     <li>Financial-grade API: JWT Secured Authorization Response Mode for
074 *         OAuth 2.0 (JARM)
075 *     <li>OAuth 2.0 Demonstrating Proof-of-Possession at the Application Layer
076 *         (DPoP) (RFC 9449).
077 *     <li>OpenID Connect Federation 1.0, section 10.1.
078 *     <li>OpenID Connect for Identity Assurance 1.0, section 8.
079 * </ul>
080 */
081@Immutable
082public class AuthenticationRequest extends AuthorizationRequest {
083        
084        
085        /**
086         * The purpose string parameter minimal length.
087         */
088        public static final int PURPOSE_MIN_LENGTH = 3;
089        
090        
091        /**
092         * The purpose string parameter maximum length.
093         */
094        public static final int PURPOSE_MAX_LENGTH = 300;
095
096
097        /**
098         * The registered parameter names.
099         */
100        private static final Set<String> REGISTERED_PARAMETER_NAMES;
101
102
103        static {
104                
105                Set<String> p = new HashSet<>(AuthorizationRequest.getRegisteredParameterNames());
106
107                p.add("nonce");
108                p.add("display");
109                p.add("max_age");
110                p.add("ui_locales");
111                p.add("claims_locales");
112                p.add("id_token_hint");
113                p.add("login_hint");
114                p.add("acr_values");
115                p.add("claims");
116                p.add("purpose");
117
118                REGISTERED_PARAMETER_NAMES = Collections.unmodifiableSet(p);
119        }
120        
121        
122        /**
123         * The nonce (required for implicit flow (unless in JAR), optional for
124         * code flow).
125         */
126        private final Nonce nonce;
127        
128        
129        /**
130         * The requested display type (optional).
131         */
132        private final Display display;
133        
134        
135        /**
136         * The required maximum authentication age, in seconds, -1 if not
137         * specified, zero implies prompt=login (optional).
138         */
139        private final int maxAge;
140
141
142        /**
143         * The end-user's preferred languages and scripts for the user 
144         * interface (optional).
145         */
146        private final List<LangTag> uiLocales;
147
148
149        /**
150         * The end-user's preferred languages and scripts for claims being 
151         * returned (optional).
152         */
153        private final List<LangTag> claimsLocales;
154
155
156        /**
157         * Previously issued ID Token passed to the authorisation server as a 
158         * hint about the end-user's current or past authenticated session with
159         * the client (optional). Should be present when {@code prompt=none} is 
160         * used.
161         */
162        private final JWT idTokenHint;
163
164
165        /**
166         * Hint to the authorisation server about the login identifier the 
167         * end-user may use to log in (optional).
168         */
169        private final String loginHint;
170
171
172        /**
173         * Requested Authentication Context Class Reference values (optional).
174         */
175        private final List<ACR> acrValues;
176
177
178        /**
179         * Individual claims to be returned (optional).
180         */
181        private final OIDCClaimsRequest claims;
182        
183        
184        /**
185         * The transaction specific purpose, for use in OpenID Connect Identity
186         * Assurance.
187         */
188        private final String purpose;
189
190
191        /**
192         * Builder for constructing OpenID Connect authentication requests.
193         */
194        public static class Builder {
195
196
197                /**
198                 * The endpoint URI (optional).
199                 */
200                private URI uri;
201
202
203                /**
204                 * The response type (required unless in JAR).
205                 */
206                private ResponseType rt;
207
208
209                /**
210                 * The client identifier (required unless in JAR).
211                 */
212                private final ClientID clientID;
213
214
215                /**
216                 * The redirection URI where the response will be sent
217                 * (required unless in JAR).
218                 */
219                private URI redirectURI;
220
221
222                /**
223                 * The scope (required unless in JAR).
224                 */
225                private Scope scope;
226
227
228                /**
229                 * The opaque value to maintain state between the request and
230                 * the callback (recommended).
231                 */
232                private State state;
233
234
235                /**
236                 * The nonce (required for implicit flow (unless in JAR),
237                 * optional for code flow).
238                 */
239                private Nonce nonce;
240
241
242                /**
243                 * The requested display type (optional).
244                 */
245                private Display display;
246
247
248                /**
249                 * The requested prompt (optional).
250                 */
251                private Prompt prompt;
252                
253                
254                /**
255                 * The DPoP JWK SHA-256 thumbprint (optional).
256                 */
257                private JWKThumbprintConfirmation dpopJKT;
258                
259                
260                /**
261                 * The OpenID Connect Federation 1.0 trust chain (optional).
262                 */
263                private TrustChain trustChain;
264
265
266                /**
267                 * The required maximum authentication age, in seconds, -1 if
268                 * not specified, zero implies prompt=login (optional).
269                 */
270                private int maxAge = -1;
271
272
273                /**
274                 * The end-user's preferred languages and scripts for the user
275                 * interface (optional).
276                 */
277                private List<LangTag> uiLocales;
278
279
280                /**
281                 * The end-user's preferred languages and scripts for claims
282                 * being returned (optional).
283                 */
284                private List<LangTag> claimsLocales;
285
286
287                /**
288                 * Previously issued ID Token passed to the authorisation
289                 * server as a hint about the end-user's current or past
290                 * authenticated session with the client (optional). Should be
291                 * present when {@code prompt=none} is used.
292                 */
293                private JWT idTokenHint;
294
295
296                /**
297                 * Hint to the authorisation server about the login identifier
298                 * the end-user may use to log in (optional).
299                 */
300                private String loginHint;
301
302
303                /**
304                 * Requested Authentication Context Class Reference values
305                 * (optional).
306                 */
307                private List<ACR> acrValues;
308
309
310                /**
311                 * Individual claims to be returned (optional).
312                 */
313                private OIDCClaimsRequest claims;
314                
315                
316                /**
317                 * The transaction specific purpose (optional).
318                 */
319                private String purpose;
320
321
322                /**
323                 * Request object (optional).
324                 */
325                private JWT requestObject;
326
327
328                /**
329                 * Request object URI (optional).
330                 */
331                private URI requestURI;
332
333
334                /**
335                 * The response mode (optional).
336                 */
337                private ResponseMode rm;
338
339
340                /**
341                 * The authorisation code challenge for PKCE (optional).
342                 */
343                private CodeChallenge codeChallenge;
344
345
346                /**
347                 * The authorisation code challenge method for PKCE (optional).
348                 */
349                private CodeChallengeMethod codeChallengeMethod;
350
351
352                /**
353                 * The RAR details (optional).
354                 */
355                private List<AuthorizationDetail> authorizationDetails;
356                
357                
358                /**
359                 * The resource URI(s) (optional).
360                 */
361                private List<URI> resources;
362                
363                
364                /**
365                 * Indicates incremental authorisation (optional).
366                 */
367                private boolean includeGrantedScopes;
368
369
370                /**
371                 * Custom parameters.
372                 */
373                private final Map<String,List<String>> customParams = new HashMap<>();
374
375
376                /**
377                 * Creates a new OpenID Connect authentication request builder.
378                 *
379                 * @param rt          The response type. Corresponds to the
380                 *                    {@code response_type} parameter. Must
381                 *                    specify a valid OpenID Connect response
382                 *                    type. Must not be {@code null}.
383                 * @param scope       The request scope. Corresponds to the
384                 *                    {@code scope} parameter. Must contain an
385                 *                    {@link OIDCScopeValue#OPENID openid
386                 *                    value}. Must not be {@code null}.
387                 * @param clientID    The client identifier. Corresponds to the
388                 *                    {@code client_id} parameter. Must not be
389                 *                    {@code null}.
390                 * @param redirectURI The redirection URI. Corresponds to the
391                 *                    {@code redirect_uri} parameter. Must not
392                 *                    be {@code null} unless set by means of
393                 *                    the optional {@code request_object} /
394                 *                    {@code request_uri} parameter.
395                 */
396                public Builder(final ResponseType rt,
397                               final Scope scope,
398                               final ClientID clientID,
399                               final URI redirectURI) {
400
401                        if (rt == null)
402                                throw new IllegalArgumentException("The response type must not be null");
403
404                        OIDCResponseTypeValidator.validate(rt);
405
406                        this.rt = rt;
407
408                        if (scope == null)
409                                throw new IllegalArgumentException("The scope must not be null");
410
411                        if (! scope.contains(OIDCScopeValue.OPENID))
412                                throw new IllegalArgumentException("The scope must include an \"openid\" value");
413
414                        this.scope = scope;
415
416                        if (clientID == null)
417                                throw new IllegalArgumentException("The client ID must not be null");
418
419                        this.clientID = clientID;
420
421                        // Check presence at build time
422                        this.redirectURI = redirectURI;
423                }
424
425
426                /**
427                 * Creates a new JWT secured OpenID Connect authentication
428                 * request (JAR) builder.
429                 *
430                 * @param requestObject The request object. Must not be
431                 *                      {@code null}.
432                 * @param clientID      The client ID. Must not be
433                 *                      {@code null}.
434                 */
435                public Builder(final JWT requestObject, final ClientID clientID) {
436                        
437                        if (requestObject == null)
438                                throw new IllegalArgumentException("The request object must not be null");
439
440                        this.requestObject = requestObject;
441                        
442                        if (clientID == null)
443                                throw new IllegalArgumentException("The client ID must not be null");
444                        
445                        this.clientID = clientID;
446                }
447
448
449                /**
450                 * Creates a new JWT secured OpenID Connect authentication
451                 * request (JAR) builder.
452                 *
453                 * @param requestURI The request object URI. Must not be
454                 *                   {@code null}.
455                 * @param clientID   The client ID. Must not be {@code null}.
456                 */
457                public Builder(final URI requestURI, final ClientID clientID) {
458                        
459                        if (requestURI == null)
460                                throw new IllegalArgumentException("The request URI must not be null");
461
462                        this.requestURI = requestURI;
463                        
464                        if (clientID == null)
465                                throw new IllegalArgumentException("The client ID must not be null");
466                        
467                        this.clientID = clientID;
468                }
469                
470                
471                /**
472                 * Creates a new OpenID Connect authentication request builder
473                 * from the specified request.
474                 *
475                 * @param request The OpenID Connect authentication request.
476                 *                Must not be {@code null}.
477                 */
478                public Builder(final AuthenticationRequest request) {
479                        uri = request.getEndpointURI();
480                        rt = request.getResponseType();
481                        clientID = request.getClientID();
482                        redirectURI = request.getRedirectionURI();
483                        scope = request.getScope();
484                        state = request.getState();
485                        nonce = request.getNonce();
486                        display = request.getDisplay();
487                        prompt = request.getPrompt();
488                        dpopJKT = request.getDPoPJWKThumbprintConfirmation();
489                        trustChain = request.getTrustChain();
490                        maxAge = request.getMaxAge();
491                        uiLocales = request.getUILocales();
492                        claimsLocales = request.getClaimsLocales();
493                        idTokenHint = request.getIDTokenHint();
494                        loginHint = request.getLoginHint();
495                        acrValues = request.getACRValues();
496                        claims = request.getOIDCClaims();
497                        purpose = request.getPurpose();
498                        requestObject = request.getRequestObject();
499                        requestURI = request.getRequestURI();
500                        rm = request.getResponseMode();
501                        codeChallenge = request.getCodeChallenge();
502                        codeChallengeMethod = request.getCodeChallengeMethod();
503                        authorizationDetails = request.getAuthorizationDetails();
504                        resources = request.getResources();
505                        includeGrantedScopes = request.includeGrantedScopes();
506                        customParams.putAll(request.getCustomParameters());
507                }
508                
509                
510                /**
511                 * Sets the response type. Corresponds to the
512                 * {@code response_type} parameter.
513                 *
514                 * @param rt The response type. Must not be {@code null}.
515                 *
516                 * @return This builder.
517                 */
518                public Builder responseType(final ResponseType rt) {
519                        
520                        if (rt == null)
521                                throw new IllegalArgumentException("The response type must not be null");
522                        
523                        this.rt = rt;
524                        return this;
525                }
526                
527                
528                /**
529                 * Sets the scope. Corresponds to the {@code scope} parameter.
530                 *
531                 * @param scope The scope. Must not be {@code null}.
532                 *
533                 * @return This builder.
534                 */
535                public Builder scope(final Scope scope) {
536                        
537                        if (scope == null)
538                                throw new IllegalArgumentException("The scope must not be null");
539                        
540                        if (! scope.contains(OIDCScopeValue.OPENID))
541                                throw new IllegalArgumentException("The scope must include an openid value");
542                        
543                        this.scope = scope;
544                        return this;
545                }
546                
547                
548                /**
549                 * Sets the redirection URI. Corresponds to the
550                 * {@code redirection_uri} parameter.
551                 *
552                 * @param redirectURI The redirection URI. Must not be
553                 *                    {@code null}.
554                 *
555                 * @return This builder.
556                 */
557                public Builder redirectionURI(final URI redirectURI) {
558                        
559                        if (redirectURI == null)
560                                throw new IllegalArgumentException("The redirection URI must not be null");
561                        
562                        this.redirectURI = redirectURI;
563                        return this;
564                }
565
566
567                /**
568                 * Sets the state. Corresponds to the recommended {@code state}
569                 * parameter.
570                 *
571                 * @param state The state, {@code null} if not specified.
572                 *
573                 * @return This builder.
574                 */
575                public Builder state(final State state) {
576                        this.state = state;
577                        return this;
578                }
579
580
581                /**
582                 * Sets the URI of the endpoint (HTTP or HTTPS) for which the
583                 * request is intended.
584                 *
585                 * @param uri The endpoint URI, {@code null} if not specified.
586                 *
587                 * @return This builder.
588                 */
589                public Builder endpointURI(final URI uri) {
590                        this.uri = uri;
591                        return this;
592                }
593
594
595                /**
596                 * Sets the nonce. Corresponds to the conditionally optional
597                 * {@code nonce} parameter.
598                 *
599                 * @param nonce The nonce, {@code null} if not specified.
600                 *
601                 * @return This builder.
602                 */
603                public Builder nonce(final Nonce nonce) {
604                        this.nonce = nonce;
605                        return this;
606                }
607
608
609                /**
610                 * Sets the requested display type. Corresponds to the optional
611                 * {@code display} parameter.
612                 *
613                 * @param display The requested display type, {@code null} if
614                 *                not specified.
615                 *
616                 * @return This builder.
617                 */
618                public Builder display(final Display display) {
619                        this.display = display;
620                        return this;
621                }
622
623
624                /**
625                 * Sets the requested prompt. Corresponds to the optional
626                 * {@code prompt} parameter.
627                 *
628                 * @param prompt The requested prompt, {@code null} if not
629                 *               specified.
630                 *
631                 * @return This builder.
632                 */
633                public Builder prompt(final Prompt prompt) {
634                        this.prompt = prompt;
635                        return this;
636                }
637                
638                
639                /**
640                 * Sets the requested prompt. Corresponds to the optional
641                 * {@code prompt} parameter.
642                 *
643                 * @param promptType The requested prompt types, {@code null}
644                 *                   if not specified.
645                 *
646                 * @return This builder.
647                 */
648                public Builder prompt(final Prompt.Type ... promptType) {
649                        if (promptType.length == 1 && promptType[0] == null) {
650                                return prompt((Prompt)null);
651                        } else {
652                                return prompt(new Prompt(promptType));
653                        }
654                }
655                
656                
657                /**
658                 * Sets the DPoP JWK SHA-256 thumbprint. Corresponds to the
659                 * optional {@code dpop_jkt} parameter.
660                 *
661                 * @param dpopJKT DPoP JWK SHA-256 thumbprint, {@code null} if
662                 *                not specified.
663                 *
664                 * @return This builder.
665                 */
666                public Builder dPoPJWKThumbprintConfirmation(final JWKThumbprintConfirmation dpopJKT) {
667                        this.dpopJKT = dpopJKT;
668                        return this;
669                }
670                
671                
672                /**
673                 * Sets the OpenID Connect Federation 1.0 trust chain.
674                 * Corresponds to the optional {@code trust_chain} parameter.
675                 *
676                 * @param trustChain The trust chain, {@code null} if not
677                 *                   specified.
678                 *
679                 * @return This builder.
680                 */
681                public Builder trustChain(final TrustChain trustChain) {
682                        this.trustChain = trustChain;
683                        return this;
684                }
685
686
687                /**
688                 * Sets the required maximum authentication age. Corresponds to
689                 * the optional {@code max_age} parameter.
690                 *
691                 * @param maxAge The maximum authentication age, in seconds; 0
692                 *               if not specified.
693                 *
694                 * @return This builder.
695                 */
696                public Builder maxAge(final int maxAge) {
697                        this.maxAge = maxAge;
698                        return this;
699                }
700
701
702                /**
703                 * Sets the end-user's preferred languages and scripts for the
704                 * user interface, ordered by preference. Corresponds to the
705                 * optional {@code ui_locales} parameter.
706                 *
707                 * @param uiLocales The preferred UI locales, {@code null} if
708                 *                  not specified.
709                 *
710                 * @return This builder.
711                 */
712                public Builder uiLocales(final List<LangTag> uiLocales) {
713                        this.uiLocales = uiLocales;
714                        return this;
715                }
716
717
718                /**
719                 * Sets the end-user's preferred languages and scripts for the
720                 * claims being returned, ordered by preference. Corresponds to
721                 * the optional {@code claims_locales} parameter.
722                 *
723                 * @param claimsLocales The preferred claims locales,
724                 *                      {@code null} if not specified.
725                 *
726                 * @return This builder.
727                 */
728                public Builder claimsLocales(final List<LangTag> claimsLocales) {
729                        this.claimsLocales = claimsLocales;
730                        return this;
731                }
732
733
734                /**
735                 * Sets the ID Token hint. Corresponds to the conditionally
736                 * optional {@code id_token_hint} parameter.
737                 *
738                 * @param idTokenHint The ID Token hint, {@code null} if not
739                 *                    specified.
740                 *
741                 * @return This builder.
742                 */
743                public Builder idTokenHint(final JWT idTokenHint) {
744                        this.idTokenHint = idTokenHint;
745                        return this;
746                }
747
748
749                /**
750                 * Sets the login hint. Corresponds to the optional
751                 * {@code login_hint} parameter.
752                 *
753                 * @param loginHint The login hint, {@code null} if not
754                 *                  specified.
755                 *
756                 * @return This builder.
757                 */
758                public Builder loginHint(final String loginHint) {
759                        this.loginHint = loginHint;
760                        return this;
761                }
762
763
764                /**
765                 * Sets the requested Authentication Context Class Reference
766                 * values. Corresponds to the optional {@code acr_values}
767                 * parameter.
768                 *
769                 * @param acrValues The requested ACR values, {@code null} if
770                 *                  not specified.
771                 *
772                 * @return This builder.
773                 */
774                public Builder acrValues(final List<ACR> acrValues) {
775                        this.acrValues = acrValues;
776                        return this;
777                }
778
779
780                /**
781                 * Sets the individual claims to be returned. Corresponds to
782                 * the optional {@code claims} parameter.
783                 *
784                 * @see #claims(OIDCClaimsRequest)
785                 *
786                 * @param claims The individual claims to be returned,
787                 *               {@code null} if not specified.
788                 *
789                 * @return This builder.
790                 */
791                @Deprecated
792                public Builder claims(final ClaimsRequest claims) {
793
794                        if (claims == null) {
795                                this.claims = null;
796                        } else {
797                                try {
798                                        this.claims = OIDCClaimsRequest.parse(claims.toJSONObject());
799                                } catch (ParseException e) {
800                                        // Should never happen
801                                        throw new IllegalArgumentException("Invalid claims: " + e.getMessage(), e);
802                                }
803                        }
804                        return this;
805                }
806
807
808                /**
809                 * Sets the individual OpenID claims to be returned.
810                 * Corresponds to the optional {@code claims} parameter.
811                 *
812                 * @param claims The individual OpenID claims to be returned,
813                 *               {@code null} if not specified.
814                 *
815                 * @return This builder.
816                 */
817                public Builder claims(final OIDCClaimsRequest claims) {
818                        this.claims = claims;
819                        return this;
820                }
821                
822                
823                /**
824                 * Sets the transaction specific purpose. Corresponds to the
825                 * optional {@code purpose} parameter.
826                 *
827                 * @param purpose The purpose, {@code null} if not specified.
828                 *
829                 * @return This builder.
830                 */
831                public Builder purpose(final String purpose) {
832                        this.purpose = purpose;
833                        return this;
834                }
835
836
837                /**
838                 * Sets the request object. Corresponds to the optional
839                 * {@code request} parameter. Must not be specified together
840                 * with a request object URI.
841                 *
842                 * @param requestObject The request object, {@code null} if not
843                 *                      specified.
844                 *
845                 * @return This builder.
846                 */
847                public Builder requestObject(final JWT requestObject) {
848                        this.requestObject = requestObject;
849                        return this;
850                }
851
852
853                /**
854                 * Sets the request object URI. Corresponds to the optional
855                 * {@code request_uri} parameter. Must not be specified
856                 * together with a request object.
857                 *
858                 * @param requestURI The request object URI, {@code null} if
859                 *                   not specified.
860                 *
861                 * @return This builder.
862                 */
863                public Builder requestURI(final URI requestURI) {
864                        this.requestURI = requestURI;
865                        return this;
866                }
867
868
869                /**
870                 * Sets the response mode. Corresponds to the optional
871                 * {@code response_mode} parameter. Use of this parameter is
872                 * not recommended unless a non-default response mode is
873                 * requested (e.g. form_post).
874                 *
875                 * @param rm The response mode, {@code null} if not specified.
876                 *
877                 * @return This builder.
878                 */
879                public Builder responseMode(final ResponseMode rm) {
880                        this.rm = rm;
881                        return this;
882                }
883                
884                
885                /**
886                 * Sets the code challenge for Proof Key for Code Exchange
887                 * (PKCE) by public OAuth clients.
888                 *
889                 * @param codeChallenge       The code challenge, {@code null}
890                 *                            if not specified.
891                 * @param codeChallengeMethod The code challenge method,
892                 *                            {@code null} if not specified.
893                 *
894                 * @return This builder.
895                 */
896                @Deprecated
897                public Builder codeChallenge(final CodeChallenge codeChallenge, final CodeChallengeMethod codeChallengeMethod) {
898                        this.codeChallenge = codeChallenge;
899                        this.codeChallengeMethod = codeChallengeMethod;
900                        return this;
901                }
902                
903                
904                /**
905                 * Sets the code challenge for Proof Key for Code Exchange
906                 * (PKCE) by public OAuth clients.
907                 *
908                 * @param codeVerifier        The code verifier to use to
909                 *                            compute the code challenge,
910                 *                            {@code null} if PKCE is not
911                 *                            specified.
912                 * @param codeChallengeMethod The code challenge method,
913                 *                            {@code null} if not specified.
914                 *                            Defaults to
915                 *                            {@link CodeChallengeMethod#PLAIN}
916                 *                            if a code verifier is specified.
917                 *
918                 * @return This builder.
919                 */
920                public Builder codeChallenge(final CodeVerifier codeVerifier, final CodeChallengeMethod codeChallengeMethod) {
921                        if (codeVerifier != null) {
922                                CodeChallengeMethod method = codeChallengeMethod != null ? codeChallengeMethod : CodeChallengeMethod.getDefault();
923                                this.codeChallenge = CodeChallenge.compute(method, codeVerifier);
924                                this.codeChallengeMethod = method;
925                        } else {
926                                this.codeChallenge = null;
927                                this.codeChallengeMethod = null;
928                        }
929                        return this;
930                }
931
932
933                /**
934                 * Sets the Rich Authorisation Request (RAR) details.
935                 *
936                 * @param authorizationDetails The authorisation details,
937                 *                             {@code null} if not specified.
938                 *
939                 * @return This builder.
940                 */
941                public Builder authorizationDetails(final List<AuthorizationDetail> authorizationDetails) {
942                        this.authorizationDetails = authorizationDetails;
943                        return this;
944                }
945                
946                
947                /**
948                 * Sets the resource server URI.
949                 *
950                 * @param resource The resource URI, {@code null} if not
951                 *                 specified.
952                 *
953                 * @return This builder.
954                 */
955                public Builder resource(final URI resource) {
956                        if (resource != null) {
957                                this.resources = Collections.singletonList(resource);
958                        } else {
959                                this.resources = null;
960                        }
961                        return this;
962                }
963                
964                
965                /**
966                 * Sets the resource server URI(s).
967                 *
968                 * @param resources The resource URI(s), {@code null} if not
969                 *                  specified.
970                 *
971                 * @return This builder.
972                 */
973                public Builder resources(final URI ... resources) {
974                        if (resources != null) {
975                                this.resources = Arrays.asList(resources);
976                        } else {
977                                this.resources = null;
978                        }
979                        return this;
980                }
981                
982                
983                /**
984                 * Requests incremental authorisation.
985                 *
986                 * @param includeGrantedScopes {@code true} to request
987                 *                             incremental authorisation.
988                 *
989                 * @return This builder.
990                 */
991                public Builder includeGrantedScopes(final boolean includeGrantedScopes) {
992                        this.includeGrantedScopes = includeGrantedScopes;
993                        return this;
994                }
995                
996                
997                /**
998                 * Sets a custom parameter.
999                 *
1000                 * @param name   The parameter name. Must not be {@code null}.
1001                 * @param values The parameter values, {@code null} if not
1002                 *               specified.
1003                 *
1004                 * @return This builder.
1005                 */
1006                public Builder customParameter(final String name, final String ... values) {
1007                        if (values == null || values.length == 0) {
1008                                customParams.remove(name);
1009                        } else {
1010                                customParams.put(name, Arrays.asList(values));
1011                        }
1012                        return this;
1013                }
1014
1015
1016                /**
1017                 * Builds a new authentication request.
1018                 *
1019                 * @return The authentication request.
1020                 */
1021                public AuthenticationRequest build() {
1022
1023                        try {
1024                                return new AuthenticationRequest(
1025                                        uri, rt, rm, scope, clientID, redirectURI, state, nonce,
1026                                        display, prompt, dpopJKT, trustChain, maxAge, uiLocales, claimsLocales,
1027                                        idTokenHint, loginHint, acrValues, claims,
1028                                        purpose,
1029                                        requestObject, requestURI,
1030                                        codeChallenge, codeChallengeMethod,
1031                                        authorizationDetails,
1032                                        resources,
1033                                        includeGrantedScopes,
1034                                        customParams);
1035
1036                        } catch (IllegalArgumentException e) {
1037                                throw new IllegalStateException(e.getMessage(), e);
1038                        }
1039                }
1040        }
1041        
1042        
1043        /**
1044         * Creates a new minimal OpenID Connect authentication request.
1045         *
1046         * @param uri         The URI of the OAuth 2.0 authorisation endpoint.
1047         *                    May be {@code null} if the {@link #toHTTPRequest}
1048         *                    method will not be used.
1049         * @param rt          The response type. Corresponds to the 
1050         *                    {@code response_type} parameter. Must specify a
1051         *                    valid OpenID Connect response type. Must not be
1052         *                    {@code null}.
1053         * @param scope       The request scope. Corresponds to the
1054         *                    {@code scope} parameter. Must contain an
1055         *                    {@link OIDCScopeValue#OPENID openid value}. Must
1056         *                    not be {@code null}.
1057         * @param clientID    The client identifier. Corresponds to the
1058         *                    {@code client_id} parameter. Must not be 
1059         *                    {@code null}.
1060         * @param redirectURI The redirection URI. Corresponds to the
1061         *                    {@code redirect_uri} parameter. Must not be 
1062         *                    {@code null}.
1063         * @param state       The state. Corresponds to the {@code state}
1064         *                    parameter. May be {@code null}.
1065         * @param nonce       The nonce. Corresponds to the {@code nonce} 
1066         *                    parameter. May be {@code null} for code flow.
1067         */
1068        public AuthenticationRequest(final URI uri,
1069                                     final ResponseType rt,
1070                                     final Scope scope,
1071                                     final ClientID clientID,
1072                                     final URI redirectURI,
1073                                     final State state,
1074                                     final Nonce nonce) {
1075
1076                // Not specified: display, prompt, maxAge, uiLocales, claimsLocales, 
1077                // idTokenHint, loginHint, acrValues, claims, purpose
1078                // codeChallenge, codeChallengeMethod
1079                this(uri, rt, null, scope, clientID, redirectURI, state, nonce,
1080                        null, null, -1, null, null,
1081                        null, null, null, (OIDCClaimsRequest) null, null,
1082                        null, null,
1083                        null, null,
1084                        null, false, null);
1085        }
1086
1087
1088        /**
1089         * Creates a new OpenID Connect authentication request with extension
1090         * and custom parameters.
1091         *
1092         * @param uri                  The URI of the OAuth 2.0 authorisation
1093         *                             endpoint. May be {@code null} if the
1094         *                             {@link #toHTTPRequest} method will not
1095         *                             be used.
1096         * @param rt                   The response type set. Corresponds to
1097         *                             the {@code response_type} parameter.
1098         *                             Must specify a valid OpenID Connect
1099         *                             response type. Must not be {@code null}.
1100         * @param rm                   The response mode. Corresponds to the
1101         *                             optional {@code response_mode}
1102         *                             parameter. Use of this parameter is not
1103         *                             recommended unless a non-default
1104         *                             response mode is requested (e.g.
1105         *                             form_post).
1106         * @param scope                The request scope. Corresponds to the
1107         *                             {@code scope} parameter. Must contain an
1108         *                             {@link OIDCScopeValue#OPENID openid
1109         *                             value}. Must not be {@code null}.
1110         * @param clientID             The client identifier. Corresponds to
1111         *                             the {@code client_id} parameter. Must
1112         *                             not be {@code null}.
1113         * @param redirectURI          The redirection URI. Corresponds to the
1114         *                             {@code redirect_uri} parameter. Must not
1115         *                             be {@code null} unless set by means of
1116         *                             the optional {@code request_object} /
1117         *                             {@code request_uri} parameter.
1118         * @param state                The state. Corresponds to the
1119         *                             recommended {@code state} parameter.
1120         *                             {@code null} if not specified.
1121         * @param nonce                The nonce. Corresponds to the
1122         *                             {@code nonce} parameter. May be
1123         *                             {@code null} for code flow.
1124         * @param display              The requested display type. Corresponds
1125         *                             to the optional {@code display}
1126         *                             parameter.
1127         *                             {@code null} if not specified.
1128         * @param prompt               The requested prompt. Corresponds to the
1129         *                             optional {@code prompt} parameter.
1130         *                             {@code null} if not specified.
1131         * @param maxAge               The required maximum authentication age,
1132         *                             in seconds. Corresponds to the optional
1133         *                             {@code max_age} parameter. -1 if not
1134         *                             specified, zero implies
1135         *                             {@code prompt=login}.
1136         * @param uiLocales            The preferred languages and scripts for
1137         *                             the user interface. Corresponds to the
1138         *                             optional {@code ui_locales} parameter.
1139         *                             {@code null} if not specified.
1140         * @param claimsLocales        The preferred languages and scripts for
1141         *                             claims being returned. Corresponds to
1142         *                             the optional {@code claims_locales}
1143         *                             parameter. {@code null} if not
1144         *                             specified.
1145         * @param idTokenHint          The ID Token hint. Corresponds to the
1146         *                             optional {@code id_token_hint}
1147         *                             parameter. {@code null} if not
1148         *                             specified.
1149         * @param loginHint            The login hint. Corresponds to the
1150         *                             optional {@code login_hint} parameter.
1151         *                             {@code null} if not specified.
1152         * @param acrValues            The requested Authentication Context
1153         *                             Class Reference values. Corresponds to
1154         *                             the optional {@code acr_values}
1155         *                             parameter. {@code null} if not
1156         *                             specified.
1157         * @param claims               The individual claims to be returned.
1158         *                             Corresponds to the optional
1159         *                             {@code claims} parameter. {@code null}
1160         *                             if not specified.
1161         * @param purpose              The transaction specific purpose,
1162         *                             {@code null} if not specified.
1163         * @param requestObject        The request object. Corresponds to the
1164         *                             optional {@code request} parameter. Must
1165         *                             not be specified together with a request
1166         *                             object URI. {@code null} if not
1167         *                             specified.
1168         * @param requestURI           The request object URI. Corresponds to
1169         *                             the optional {@code request_uri}
1170         *                             parameter. Must not be specified
1171         *                             together with a request object.
1172         *                             {@code null} if not specified.
1173         * @param codeChallenge        The code challenge for PKCE,
1174         *                             {@code null} if not specified.
1175         * @param codeChallengeMethod  The code challenge method for PKCE,
1176         *                             {@code null} if not specified.
1177         * @param resources            The resource URI(s), {@code null} if not
1178         *                             specified.
1179         * @param includeGrantedScopes {@code true} to request incremental
1180         *                             authorisation.
1181         * @param customParams         Additional custom parameters, empty map
1182         *                             or {@code null} if none.
1183         */
1184        @Deprecated
1185        public AuthenticationRequest(final URI uri,
1186                                     final ResponseType rt,
1187                                     final ResponseMode rm,
1188                                     final Scope scope,
1189                                     final ClientID clientID,
1190                                     final URI redirectURI,
1191                                     final State state,
1192                                     final Nonce nonce,
1193                                     final Display display,
1194                                     final Prompt prompt,
1195                                     final int maxAge,
1196                                     final List<LangTag> uiLocales,
1197                                     final List<LangTag> claimsLocales,
1198                                     final JWT idTokenHint,
1199                                     final String loginHint,
1200                                     final List<ACR> acrValues,
1201                                     final ClaimsRequest claims,
1202                                     final String purpose,
1203                                     final JWT requestObject,
1204                                     final URI requestURI,
1205                                     final CodeChallenge codeChallenge,
1206                                     final CodeChallengeMethod codeChallengeMethod,
1207                                     final List<URI> resources,
1208                                     final boolean includeGrantedScopes,
1209                                     final Map<String,List<String>> customParams) {
1210
1211                this(uri, rt, rm, scope, clientID, redirectURI, state, nonce,
1212                        display, prompt, maxAge, uiLocales, claimsLocales,
1213                        idTokenHint, loginHint, acrValues, toOIDCClaimsRequestWithSilentFail(claims), purpose,
1214                        requestObject, requestURI,
1215                        codeChallenge, codeChallengeMethod,
1216                        resources, includeGrantedScopes, customParams);
1217        }
1218
1219        
1220        /**
1221         * Creates a new OpenID Connect authentication request with extension
1222         * and custom parameters.
1223         *
1224         * @param uri                  The URI of the OAuth 2.0 authorisation
1225         *                             endpoint. May be {@code null} if the
1226         *                             {@link #toHTTPRequest} method will not
1227         *                             be used.
1228         * @param rt                   The response type set. Corresponds to
1229         *                             the {@code response_type} parameter.
1230         *                             Must specify a valid OpenID Connect
1231         *                             response type. Must not be {@code null}.
1232         * @param rm                   The response mode. Corresponds to the
1233         *                             optional {@code response_mode}
1234         *                             parameter. Use of this parameter is not
1235         *                             recommended unless a non-default
1236         *                             response mode is requested (e.g.
1237         *                             form_post).
1238         * @param scope                The request scope. Corresponds to the
1239         *                             {@code scope} parameter. Must contain an
1240         *                             {@link OIDCScopeValue#OPENID openid
1241         *                             value}. Must not be {@code null}.
1242         * @param clientID             The client identifier. Corresponds to
1243         *                             the {@code client_id} parameter. Must
1244         *                             not be {@code null}.
1245         * @param redirectURI          The redirection URI. Corresponds to the
1246         *                             {@code redirect_uri} parameter. Must not
1247         *                             be {@code null} unless set by means of
1248         *                             the optional {@code request_object} /
1249         *                             {@code request_uri} parameter.
1250         * @param state                The state. Corresponds to the
1251         *                             recommended {@code state} parameter.
1252         *                             {@code null} if not specified.
1253         * @param nonce                The nonce. Corresponds to the
1254         *                             {@code nonce} parameter. May be
1255         *                             {@code null} for code flow.
1256         * @param display              The requested display type. Corresponds
1257         *                             to the optional {@code display}
1258         *                             parameter.
1259         *                             {@code null} if not specified.
1260         * @param prompt               The requested prompt. Corresponds to the
1261         *                             optional {@code prompt} parameter.
1262         *                             {@code null} if not specified.
1263         * @param maxAge               The required maximum authentication age,
1264         *                             in seconds. Corresponds to the optional
1265         *                             {@code max_age} parameter. -1 if not
1266         *                             specified, zero implies
1267         *                             {@code prompt=login}.
1268         * @param uiLocales            The preferred languages and scripts for
1269         *                             the user interface. Corresponds to the
1270         *                             optional {@code ui_locales} parameter.
1271         *                             {@code null} if not specified.
1272         * @param claimsLocales        The preferred languages and scripts for
1273         *                             claims being returned. Corresponds to
1274         *                             the optional {@code claims_locales}
1275         *                             parameter. {@code null} if not
1276         *                             specified.
1277         * @param idTokenHint          The ID Token hint. Corresponds to the
1278         *                             optional {@code id_token_hint}
1279         *                             parameter. {@code null} if not
1280         *                             specified.
1281         * @param loginHint            The login hint. Corresponds to the
1282         *                             optional {@code login_hint} parameter.
1283         *                             {@code null} if not specified.
1284         * @param acrValues            The requested Authentication Context
1285         *                             Class Reference values. Corresponds to
1286         *                             the optional {@code acr_values}
1287         *                             parameter. {@code null} if not
1288         *                             specified.
1289         * @param claims               The individual OpenID claims to be
1290         *                             returned. Corresponds to the optional
1291         *                             {@code claims} parameter. {@code null}
1292         *                             if not specified.
1293         * @param purpose              The transaction specific purpose,
1294         *                             {@code null} if not specified.
1295         * @param requestObject        The request object. Corresponds to the
1296         *                             optional {@code request} parameter. Must
1297         *                             not be specified together with a request
1298         *                             object URI. {@code null} if not
1299         *                             specified.
1300         * @param requestURI           The request object URI. Corresponds to
1301         *                             the optional {@code request_uri}
1302         *                             parameter. Must not be specified
1303         *                             together with a request object.
1304         *                             {@code null} if not specified.
1305         * @param codeChallenge        The code challenge for PKCE,
1306         *                             {@code null} if not specified.
1307         * @param codeChallengeMethod  The code challenge method for PKCE,
1308         *                             {@code null} if not specified.
1309         * @param resources            The resource URI(s), {@code null} if not
1310         *                             specified.
1311         * @param includeGrantedScopes {@code true} to request incremental
1312         *                             authorisation.
1313         * @param customParams         Additional custom parameters, empty map
1314         *                             or {@code null} if none.
1315         */
1316        @Deprecated
1317        public AuthenticationRequest(final URI uri,
1318                                     final ResponseType rt,
1319                                     final ResponseMode rm,
1320                                     final Scope scope,
1321                                     final ClientID clientID,
1322                                     final URI redirectURI,
1323                                     final State state,
1324                                     final Nonce nonce,
1325                                     final Display display,
1326                                     final Prompt prompt,
1327                                     final int maxAge,
1328                                     final List<LangTag> uiLocales,
1329                                     final List<LangTag> claimsLocales,
1330                                     final JWT idTokenHint,
1331                                     final String loginHint,
1332                                     final List<ACR> acrValues,
1333                                     final OIDCClaimsRequest claims,
1334                                     final String purpose,
1335                                     final JWT requestObject,
1336                                     final URI requestURI,
1337                                     final CodeChallenge codeChallenge,
1338                                     final CodeChallengeMethod codeChallengeMethod,
1339                                     final List<URI> resources,
1340                                     final boolean includeGrantedScopes,
1341                                     final Map<String,List<String>> customParams) {
1342
1343                this(uri, rt, rm, scope, clientID, redirectURI, state, nonce, display, prompt, null, null,
1344                        maxAge, uiLocales, claimsLocales, idTokenHint, loginHint, acrValues, claims, purpose,
1345                        requestObject, requestURI, codeChallenge, codeChallengeMethod,
1346                        resources, includeGrantedScopes,
1347                        customParams);
1348        }
1349
1350        
1351        /**
1352         * Creates a new OpenID Connect authentication request with extension
1353         * and custom parameters.
1354         *
1355         * @param uri                  The URI of the OAuth 2.0 authorisation
1356         *                             endpoint. May be {@code null} if the
1357         *                             {@link #toHTTPRequest} method will not
1358         *                             be used.
1359         * @param rt                   The response type set. Corresponds to
1360         *                             the {@code response_type} parameter.
1361         *                             Must specify a valid OpenID Connect
1362         *                             response type. Must not be {@code null}.
1363         * @param rm                   The response mode. Corresponds to the
1364         *                             optional {@code response_mode}
1365         *                             parameter. Use of this parameter is not
1366         *                             recommended unless a non-default
1367         *                             response mode is requested (e.g.
1368         *                             form_post).
1369         * @param scope                The request scope. Corresponds to the
1370         *                             {@code scope} parameter. Must contain an
1371         *                             {@link OIDCScopeValue#OPENID openid
1372         *                             value}. Must not be {@code null}.
1373         * @param clientID             The client identifier. Corresponds to
1374         *                             the {@code client_id} parameter. Must
1375         *                             not be {@code null}.
1376         * @param redirectURI          The redirection URI. Corresponds to the
1377         *                             {@code redirect_uri} parameter. Must not
1378         *                             be {@code null} unless set by means of
1379         *                             the optional {@code request_object} /
1380         *                             {@code request_uri} parameter.
1381         * @param state                The state. Corresponds to the
1382         *                             recommended {@code state} parameter.
1383         *                             {@code null} if not specified.
1384         * @param nonce                The nonce. Corresponds to the
1385         *                             {@code nonce} parameter. May be
1386         *                             {@code null} for code flow.
1387         * @param display              The requested display type. Corresponds
1388         *                             to the optional {@code display}
1389         *                             parameter.
1390         *                             {@code null} if not specified.
1391         * @param prompt               The requested prompt. Corresponds to the
1392         *                             optional {@code prompt} parameter.
1393         *                             {@code null} if not specified.
1394         * @param dpopJKT              The DPoP JWK SHA-256 thumbprint,
1395         *                             {@code null} if not specified.
1396         * @param maxAge               The required maximum authentication age,
1397         *                             in seconds. Corresponds to the optional
1398         *                             {@code max_age} parameter. -1 if not
1399         *                             specified, zero implies
1400         *                             {@code prompt=login}.
1401         * @param uiLocales            The preferred languages and scripts for
1402         *                             the user interface. Corresponds to the
1403         *                             optional {@code ui_locales} parameter.
1404         *                             {@code null} if not specified.
1405         * @param claimsLocales        The preferred languages and scripts for
1406         *                             claims being returned. Corresponds to
1407         *                             the optional {@code claims_locales}
1408         *                             parameter. {@code null} if not
1409         *                             specified.
1410         * @param idTokenHint          The ID Token hint. Corresponds to the
1411         *                             optional {@code id_token_hint}
1412         *                             parameter. {@code null} if not
1413         *                             specified.
1414         * @param loginHint            The login hint. Corresponds to the
1415         *                             optional {@code login_hint} parameter.
1416         *                             {@code null} if not specified.
1417         * @param acrValues            The requested Authentication Context
1418         *                             Class Reference values. Corresponds to
1419         *                             the optional {@code acr_values}
1420         *                             parameter. {@code null} if not
1421         *                             specified.
1422         * @param claims               The individual OpenID claims to be
1423         *                             returned. Corresponds to the optional
1424         *                             {@code claims} parameter. {@code null}
1425         *                             if not specified.
1426         * @param purpose              The transaction specific purpose,
1427         *                             {@code null} if not specified.
1428         * @param requestObject        The request object. Corresponds to the
1429         *                             optional {@code request} parameter. Must
1430         *                             not be specified together with a request
1431         *                             object URI. {@code null} if not
1432         *                             specified.
1433         * @param requestURI           The request object URI. Corresponds to
1434         *                             the optional {@code request_uri}
1435         *                             parameter. Must not be specified
1436         *                             together with a request object.
1437         *                             {@code null} if not specified.
1438         * @param codeChallenge        The code challenge for PKCE,
1439         *                             {@code null} if not specified.
1440         * @param codeChallengeMethod  The code challenge method for PKCE,
1441         *                             {@code null} if not specified.
1442         * @param resources            The resource URI(s), {@code null} if not
1443         *                             specified.
1444         * @param includeGrantedScopes {@code true} to request incremental
1445         *                             authorisation.
1446         * @param customParams         Additional custom parameters, empty map
1447         *                             or {@code null} if none.
1448         */
1449        @Deprecated
1450        public AuthenticationRequest(final URI uri,
1451                                     final ResponseType rt,
1452                                     final ResponseMode rm,
1453                                     final Scope scope,
1454                                     final ClientID clientID,
1455                                     final URI redirectURI,
1456                                     final State state,
1457                                     final Nonce nonce,
1458                                     final Display display,
1459                                     final Prompt prompt,
1460                                     final JWKThumbprintConfirmation dpopJKT,
1461                                     final int maxAge,
1462                                     final List<LangTag> uiLocales,
1463                                     final List<LangTag> claimsLocales,
1464                                     final JWT idTokenHint,
1465                                     final String loginHint,
1466                                     final List<ACR> acrValues,
1467                                     final OIDCClaimsRequest claims,
1468                                     final String purpose,
1469                                     final JWT requestObject,
1470                                     final URI requestURI,
1471                                     final CodeChallenge codeChallenge,
1472                                     final CodeChallengeMethod codeChallengeMethod,
1473                                     final List<URI> resources,
1474                                     final boolean includeGrantedScopes,
1475                                     final Map<String,List<String>> customParams) {
1476                
1477                this(uri, rt, rm, scope, clientID, redirectURI, state, nonce, display, prompt, dpopJKT, null,
1478                        maxAge, uiLocales, claimsLocales, idTokenHint, loginHint, acrValues, claims, purpose,
1479                        requestObject, requestURI, codeChallenge, codeChallengeMethod,
1480                        resources, includeGrantedScopes,
1481                        customParams);
1482        }
1483
1484        
1485        /**
1486         * Creates a new OpenID Connect authentication request with extension
1487         * and custom parameters.
1488         *
1489         * @param uri                  The URI of the OAuth 2.0 authorisation
1490         *                             endpoint. May be {@code null} if the
1491         *                             {@link #toHTTPRequest} method will not
1492         *                             be used.
1493         * @param rt                   The response type set. Corresponds to
1494         *                             the {@code response_type} parameter.
1495         *                             Must specify a valid OpenID Connect
1496         *                             response type. Must not be {@code null}.
1497         * @param rm                   The response mode. Corresponds to the
1498         *                             optional {@code response_mode}
1499         *                             parameter. Use of this parameter is not
1500         *                             recommended unless a non-default
1501         *                             response mode is requested (e.g.
1502         *                             form_post).
1503         * @param scope                The request scope. Corresponds to the
1504         *                             {@code scope} parameter. Must contain an
1505         *                             {@link OIDCScopeValue#OPENID openid
1506         *                             value}. Must not be {@code null}.
1507         * @param clientID             The client identifier. Corresponds to
1508         *                             the {@code client_id} parameter. Must
1509         *                             not be {@code null}.
1510         * @param redirectURI          The redirection URI. Corresponds to the
1511         *                             {@code redirect_uri} parameter. Must not
1512         *                             be {@code null} unless set by means of
1513         *                             the optional {@code request_object} /
1514         *                             {@code request_uri} parameter.
1515         * @param state                The state. Corresponds to the
1516         *                             recommended {@code state} parameter.
1517         *                             {@code null} if not specified.
1518         * @param nonce                The nonce. Corresponds to the
1519         *                             {@code nonce} parameter. May be
1520         *                             {@code null} for code flow.
1521         * @param display              The requested display type. Corresponds
1522         *                             to the optional {@code display}
1523         *                             parameter.
1524         *                             {@code null} if not specified.
1525         * @param prompt               The requested prompt. Corresponds to the
1526         *                             optional {@code prompt} parameter.
1527         *                             {@code null} if not specified.
1528         * @param dpopJKT              The DPoP JWK SHA-256 thumbprint,
1529         *                             {@code null} if not specified.
1530         * @param trustChain           The OpenID Connect Federation 1.0 trust
1531         *                             chain, {@code null} if not specified.
1532         * @param maxAge               The required maximum authentication age,
1533         *                             in seconds. Corresponds to the optional
1534         *                             {@code max_age} parameter. -1 if not
1535         *                             specified, zero implies
1536         *                             {@code prompt=login}.
1537         * @param uiLocales            The preferred languages and scripts for
1538         *                             the user interface. Corresponds to the
1539         *                             optional {@code ui_locales} parameter.
1540         *                             {@code null} if not specified.
1541         * @param claimsLocales        The preferred languages and scripts for
1542         *                             claims being returned. Corresponds to
1543         *                             the optional {@code claims_locales}
1544         *                             parameter. {@code null} if not
1545         *                             specified.
1546         * @param idTokenHint          The ID Token hint. Corresponds to the
1547         *                             optional {@code id_token_hint}
1548         *                             parameter. {@code null} if not
1549         *                             specified.
1550         * @param loginHint            The login hint. Corresponds to the
1551         *                             optional {@code login_hint} parameter.
1552         *                             {@code null} if not specified.
1553         * @param acrValues            The requested Authentication Context
1554         *                             Class Reference values. Corresponds to
1555         *                             the optional {@code acr_values}
1556         *                             parameter. {@code null} if not
1557         *                             specified.
1558         * @param claims               The individual OpenID claims to be
1559         *                             returned. Corresponds to the optional
1560         *                             {@code claims} parameter. {@code null}
1561         *                             if not specified.
1562         * @param purpose              The transaction specific purpose,
1563         *                             {@code null} if not specified.
1564         * @param requestObject        The request object. Corresponds to the
1565         *                             optional {@code request} parameter. Must
1566         *                             not be specified together with a request
1567         *                             object URI. {@code null} if not
1568         *                             specified.
1569         * @param requestURI           The request object URI. Corresponds to
1570         *                             the optional {@code request_uri}
1571         *                             parameter. Must not be specified
1572         *                             together with a request object.
1573         *                             {@code null} if not specified.
1574         * @param codeChallenge        The code challenge for PKCE,
1575         *                             {@code null} if not specified.
1576         * @param codeChallengeMethod  The code challenge method for PKCE,
1577         *                             {@code null} if not specified.
1578         * @param resources            The resource URI(s), {@code null} if not
1579         *                             specified.
1580         * @param includeGrantedScopes {@code true} to request incremental
1581         *                             authorisation.
1582         * @param customParams         Additional custom parameters, empty map
1583         *                             or {@code null} if none.
1584         */
1585        @Deprecated
1586        public AuthenticationRequest(final URI uri,
1587                                     final ResponseType rt,
1588                                     final ResponseMode rm,
1589                                     final Scope scope,
1590                                     final ClientID clientID,
1591                                     final URI redirectURI,
1592                                     final State state,
1593                                     final Nonce nonce,
1594                                     final Display display,
1595                                     final Prompt prompt,
1596                                     final JWKThumbprintConfirmation dpopJKT,
1597                                     final TrustChain trustChain,
1598                                     final int maxAge,
1599                                     final List<LangTag> uiLocales,
1600                                     final List<LangTag> claimsLocales,
1601                                     final JWT idTokenHint,
1602                                     final String loginHint,
1603                                     final List<ACR> acrValues,
1604                                     final OIDCClaimsRequest claims,
1605                                     final String purpose,
1606                                     final JWT requestObject,
1607                                     final URI requestURI,
1608                                     final CodeChallenge codeChallenge,
1609                                     final CodeChallengeMethod codeChallengeMethod,
1610                                     final List<URI> resources,
1611                                     final boolean includeGrantedScopes,
1612                                     final Map<String,List<String>> customParams) {
1613
1614                this(uri, rt, rm, scope, clientID, redirectURI, state, nonce, display, prompt,
1615                        dpopJKT, trustChain,
1616                        maxAge, uiLocales, claimsLocales, idTokenHint, loginHint, acrValues, claims, purpose,
1617                        requestObject, requestURI,
1618                        codeChallenge, codeChallengeMethod,
1619                        null, resources, includeGrantedScopes,
1620                        customParams);
1621        }
1622
1623
1624        /**
1625         * Creates a new OpenID Connect authentication request with extension
1626         * and custom parameters.
1627         *
1628         * @param uri                  The URI of the OAuth 2.0 authorisation
1629         *                             endpoint. May be {@code null} if the
1630         *                             {@link #toHTTPRequest} method will not
1631         *                             be used.
1632         * @param rt                   The response type set. Corresponds to
1633         *                             the {@code response_type} parameter.
1634         *                             Must specify a valid OpenID Connect
1635         *                             response type. Must not be {@code null}.
1636         * @param rm                   The response mode. Corresponds to the
1637         *                             optional {@code response_mode}
1638         *                             parameter. Use of this parameter is not
1639         *                             recommended unless a non-default
1640         *                             response mode is requested (e.g.
1641         *                             form_post).
1642         * @param scope                The request scope. Corresponds to the
1643         *                             {@code scope} parameter. Must contain an
1644         *                             {@link OIDCScopeValue#OPENID openid
1645         *                             value}. Must not be {@code null}.
1646         * @param clientID             The client identifier. Corresponds to
1647         *                             the {@code client_id} parameter. Must
1648         *                             not be {@code null}.
1649         * @param redirectURI          The redirection URI. Corresponds to the
1650         *                             {@code redirect_uri} parameter. Must not
1651         *                             be {@code null} unless set by means of
1652         *                             the optional {@code request_object} /
1653         *                             {@code request_uri} parameter.
1654         * @param state                The state. Corresponds to the
1655         *                             recommended {@code state} parameter.
1656         *                             {@code null} if not specified.
1657         * @param nonce                The nonce. Corresponds to the
1658         *                             {@code nonce} parameter. May be
1659         *                             {@code null} for code flow.
1660         * @param display              The requested display type. Corresponds
1661         *                             to the optional {@code display}
1662         *                             parameter.
1663         *                             {@code null} if not specified.
1664         * @param prompt               The requested prompt. Corresponds to the
1665         *                             optional {@code prompt} parameter.
1666         *                             {@code null} if not specified.
1667         * @param dpopJKT              The DPoP JWK SHA-256 thumbprint,
1668         *                             {@code null} if not specified.
1669         * @param trustChain           The OpenID Connect Federation 1.0 trust
1670         *                             chain, {@code null} if not specified.
1671         * @param maxAge               The required maximum authentication age,
1672         *                             in seconds. Corresponds to the optional
1673         *                             {@code max_age} parameter. -1 if not
1674         *                             specified, zero implies
1675         *                             {@code prompt=login}.
1676         * @param uiLocales            The preferred languages and scripts for
1677         *                             the user interface. Corresponds to the
1678         *                             optional {@code ui_locales} parameter.
1679         *                             {@code null} if not specified.
1680         * @param claimsLocales        The preferred languages and scripts for
1681         *                             claims being returned. Corresponds to
1682         *                             the optional {@code claims_locales}
1683         *                             parameter. {@code null} if not
1684         *                             specified.
1685         * @param idTokenHint          The ID Token hint. Corresponds to the
1686         *                             optional {@code id_token_hint}
1687         *                             parameter. {@code null} if not
1688         *                             specified.
1689         * @param loginHint            The login hint. Corresponds to the
1690         *                             optional {@code login_hint} parameter.
1691         *                             {@code null} if not specified.
1692         * @param acrValues            The requested Authentication Context
1693         *                             Class Reference values. Corresponds to
1694         *                             the optional {@code acr_values}
1695         *                             parameter. {@code null} if not
1696         *                             specified.
1697         * @param claims               The individual OpenID claims to be
1698         *                             returned. Corresponds to the optional
1699         *                             {@code claims} parameter. {@code null}
1700         *                             if not specified.
1701         * @param purpose              The transaction specific purpose,
1702         *                             {@code null} if not specified.
1703         * @param requestObject        The request object. Corresponds to the
1704         *                             optional {@code request} parameter. Must
1705         *                             not be specified together with a request
1706         *                             object URI. {@code null} if not
1707         *                             specified.
1708         * @param requestURI           The request object URI. Corresponds to
1709         *                             the optional {@code request_uri}
1710         *                             parameter. Must not be specified
1711         *                             together with a request object.
1712         *                             {@code null} if not specified.
1713         * @param codeChallenge        The code challenge for PKCE,
1714         *                             {@code null} if not specified.
1715         * @param codeChallengeMethod  The code challenge method for PKCE,
1716         *                             {@code null} if not specified.
1717         * @param authorizationDetails The authorisation details,
1718         *                             {@code null} if not specified.
1719         * @param resources            The resource URI(s), {@code null} if not
1720         *                             specified.
1721         * @param includeGrantedScopes {@code true} to request incremental
1722         *                             authorisation.
1723         * @param customParams         Additional custom parameters, empty map
1724         *                             or {@code null} if none.
1725         */
1726        public AuthenticationRequest(final URI uri,
1727                                     final ResponseType rt,
1728                                     final ResponseMode rm,
1729                                     final Scope scope,
1730                                     final ClientID clientID,
1731                                     final URI redirectURI,
1732                                     final State state,
1733                                     final Nonce nonce,
1734                                     final Display display,
1735                                     final Prompt prompt,
1736                                     final JWKThumbprintConfirmation dpopJKT,
1737                                     final TrustChain trustChain,
1738                                     final int maxAge,
1739                                     final List<LangTag> uiLocales,
1740                                     final List<LangTag> claimsLocales,
1741                                     final JWT idTokenHint,
1742                                     final String loginHint,
1743                                     final List<ACR> acrValues,
1744                                     final OIDCClaimsRequest claims,
1745                                     final String purpose,
1746                                     final JWT requestObject,
1747                                     final URI requestURI,
1748                                     final CodeChallenge codeChallenge,
1749                                     final CodeChallengeMethod codeChallengeMethod,
1750                                     final List<AuthorizationDetail> authorizationDetails,
1751                                     final List<URI> resources,
1752                                     final boolean includeGrantedScopes,
1753                                     final Map<String,List<String>> customParams) {
1754
1755                super(uri, rt, rm, clientID, redirectURI, scope, state,
1756                        codeChallenge, codeChallengeMethod,
1757                        authorizationDetails, resources, includeGrantedScopes,
1758                        requestObject, requestURI, prompt, dpopJKT, trustChain, customParams);
1759
1760                if (! specifiesRequestObject()) {
1761
1762                        // Check parameters required by OpenID Connect if no JAR
1763
1764                        if (redirectURI == null)
1765                                throw new IllegalArgumentException("The redirection URI must not be null");
1766
1767                        OIDCResponseTypeValidator.validate(rt);
1768
1769                        if (scope == null)
1770                                throw new IllegalArgumentException("The scope must not be null");
1771
1772                        if (!scope.contains(OIDCScopeValue.OPENID))
1773                                throw new IllegalArgumentException("The scope must include an \"openid\" value");
1774
1775                        // Check nonce requirement
1776                        if (nonce == null && Nonce.isRequired(rt)) {
1777                                throw new IllegalArgumentException("Nonce required for response_type=" + rt);
1778                        }
1779                }
1780
1781                this.nonce = nonce;
1782
1783                // Optional parameters
1784                this.display = display;
1785                this.maxAge = maxAge;
1786
1787                if (uiLocales != null)
1788                        this.uiLocales = Collections.unmodifiableList(uiLocales);
1789                else
1790                        this.uiLocales = null;
1791
1792                if (claimsLocales != null)
1793                        this.claimsLocales = Collections.unmodifiableList(claimsLocales);
1794                else
1795                        this.claimsLocales = null;
1796
1797                this.idTokenHint = idTokenHint;
1798                this.loginHint = loginHint;
1799
1800                if (acrValues != null)
1801                        this.acrValues = Collections.unmodifiableList(acrValues);
1802                else
1803                        this.acrValues = null;
1804
1805                this.claims = claims;
1806
1807                if (purpose != null) {
1808                        if (purpose.length() < PURPOSE_MIN_LENGTH) {
1809                                throw new IllegalArgumentException("The purpose must not be shorter than " + PURPOSE_MIN_LENGTH + " characters");
1810                        }
1811                        if (purpose.length() > PURPOSE_MAX_LENGTH) {
1812                                throw new IllegalArgumentException("The purpose must not be longer than " + PURPOSE_MAX_LENGTH +" characters");
1813                        }
1814                }
1815
1816                this.purpose = purpose;
1817        }
1818
1819
1820        /**
1821         * Returns the registered (standard) OpenID Connect authentication
1822         * request parameter names.
1823         *
1824         * @return The registered OpenID Connect authentication request
1825         *         parameter names, as a unmodifiable set.
1826         */
1827        public static Set<String> getRegisteredParameterNames() {
1828
1829                return REGISTERED_PARAMETER_NAMES;
1830        }
1831        
1832        
1833        /**
1834         * Returns the nonce. Corresponds to the conditionally optional 
1835         * {@code nonce} parameter.
1836         *
1837         * @return The nonce, {@code null} if not specified.
1838         */
1839        public Nonce getNonce() {
1840        
1841                return nonce;
1842        }
1843        
1844        
1845        /**
1846         * Returns the requested display type. Corresponds to the optional
1847         * {@code display} parameter.
1848         *
1849         * @return The requested display type, {@code null} if not specified.
1850         */
1851        public Display getDisplay() {
1852        
1853                return display;
1854        }
1855        
1856        
1857        /**
1858         * Returns the required maximum authentication age. Corresponds to the
1859         * optional {@code max_age} parameter.
1860         *
1861         * @return The maximum authentication age, in seconds; -1 if not
1862         *         specified, zero implies {@code prompt=login}.
1863         */
1864        public int getMaxAge() {
1865        
1866                return maxAge;
1867        }
1868
1869
1870        /**
1871         * Returns the end-user's preferred languages and scripts for the user
1872         * interface, ordered by preference. Corresponds to the optional
1873         * {@code ui_locales} parameter.
1874         *
1875         * @return The preferred UI locales, {@code null} if not specified.
1876         */
1877        public List<LangTag> getUILocales() {
1878
1879                return uiLocales;
1880        }
1881
1882
1883        /**
1884         * Returns the end-user's preferred languages and scripts for the
1885         * claims being returned, ordered by preference. Corresponds to the
1886         * optional {@code claims_locales} parameter.
1887         *
1888         * @return The preferred claims locales, {@code null} if not specified.
1889         */
1890        public List<LangTag> getClaimsLocales() {
1891
1892                return claimsLocales;
1893        }
1894
1895
1896        /**
1897         * Returns the ID Token hint. Corresponds to the conditionally optional 
1898         * {@code id_token_hint} parameter.
1899         *
1900         * @return The ID Token hint, {@code null} if not specified.
1901         */
1902        public JWT getIDTokenHint() {
1903        
1904                return idTokenHint;
1905        }
1906
1907
1908        /**
1909         * Returns the login hint. Corresponds to the optional {@code login_hint} 
1910         * parameter.
1911         *
1912         * @return The login hint, {@code null} if not specified.
1913         */
1914        public String getLoginHint() {
1915
1916                return loginHint;
1917        }
1918
1919
1920        /**
1921         * Returns the requested Authentication Context Class Reference values.
1922         * Corresponds to the optional {@code acr_values} parameter.
1923         *
1924         * @return The requested ACR values, {@code null} if not specified.
1925         */
1926        public List<ACR> getACRValues() {
1927
1928                return acrValues;
1929        }
1930
1931
1932        /**
1933         * Returns the individual claims to be returned. Corresponds to the 
1934         * optional {@code claims} parameter.
1935         *
1936         * @see #getOIDCClaims()
1937         *
1938         * @return The individual claims to be returned, {@code null} if not
1939         *         specified.
1940         */
1941        @Deprecated
1942        public ClaimsRequest getClaims() {
1943
1944                return toClaimsRequestWithSilentFail(claims);
1945        }
1946        
1947        
1948        private static OIDCClaimsRequest toOIDCClaimsRequestWithSilentFail(final ClaimsRequest claims) {
1949                if (claims == null) {
1950                        return null;
1951                }
1952                try {
1953                        return OIDCClaimsRequest.parse(claims.toJSONObject());
1954                } catch (ParseException e) {
1955                        return null;
1956                }
1957        }
1958        
1959        
1960        private static ClaimsRequest toClaimsRequestWithSilentFail(final OIDCClaimsRequest claims) {
1961                if (claims == null) {
1962                        return null;
1963                }
1964                try {
1965                        return ClaimsRequest.parse(claims.toJSONObject());
1966                } catch (ParseException e) {
1967                        return null;
1968                }
1969        }
1970
1971
1972        /**
1973         * Returns the individual OpenID claims to be returned. Corresponds to
1974         * the optional {@code claims} parameter.
1975         *
1976         * @return The individual claims to be returned, {@code null} if not
1977         *         specified.
1978         */
1979        public OIDCClaimsRequest getOIDCClaims() {
1980
1981                return claims;
1982        }
1983        
1984        
1985        /**
1986         * Returns the transaction specific purpose. Corresponds to the
1987         * optional {@code purpose} parameter.
1988         *
1989         * @return The purpose, {@code null} if not specified.
1990         */
1991        public String getPurpose() {
1992                
1993                return purpose;
1994        }
1995
1996
1997        @Override
1998        public Map<String,List<String>> toParameters() {
1999
2000                Map <String,List<String>> params = super.toParameters();
2001                
2002                if (nonce != null)
2003                        params.put("nonce", Collections.singletonList(nonce.toString()));
2004                
2005                if (display != null)
2006                        params.put("display", Collections.singletonList(display.toString()));
2007
2008                if (maxAge >= 0)
2009                        params.put("max_age", Collections.singletonList("" + maxAge));
2010
2011                if (uiLocales != null) {
2012                        params.put("ui_locales", Collections.singletonList(LangTagUtils.concat(uiLocales)));
2013                }
2014
2015                if (CollectionUtils.isNotEmpty(claimsLocales)) {
2016                        params.put("claims_locales", Collections.singletonList(LangTagUtils.concat(claimsLocales)));
2017                }
2018
2019                if (idTokenHint != null) {
2020                
2021                        try {
2022                                params.put("id_token_hint", Collections.singletonList(idTokenHint.serialize()));
2023                                
2024                        } catch (IllegalStateException e) {
2025                        
2026                                throw new SerializeException("Couldn't serialize ID token hint: " + e.getMessage(), e);
2027                        }
2028                }
2029
2030                if (loginHint != null)
2031                        params.put("login_hint", Collections.singletonList(loginHint));
2032
2033                if (acrValues != null) {
2034
2035                        StringBuilder sb = new StringBuilder();
2036
2037                        for (ACR acr: acrValues) {
2038
2039                                if (sb.length() > 0)
2040                                        sb.append(' ');
2041
2042                                sb.append(acr.toString());
2043                        }
2044
2045                        params.put("acr_values", Collections.singletonList(sb.toString()));
2046                }
2047                        
2048
2049                if (claims != null)
2050                        params.put("claims", Collections.singletonList(claims.toJSONObject().toString()));
2051                
2052                if (purpose != null)
2053                        params.put("purpose", Collections.singletonList(purpose));
2054
2055                return params;
2056        }
2057        
2058        
2059        @Override
2060        public JWTClaimsSet toJWTClaimsSet() {
2061                
2062                JWTClaimsSet jwtClaimsSet = super.toJWTClaimsSet();
2063                
2064                if (jwtClaimsSet.getClaim("max_age") != null) {
2065                        // Convert max_age to number in JSON object
2066                        try {
2067                                String maxAgeString = jwtClaimsSet.getStringClaim("max_age");
2068                                JWTClaimsSet.Builder builder = new JWTClaimsSet.Builder(jwtClaimsSet);
2069                                builder.claim("max_age", Integer.parseInt(maxAgeString));
2070                                return builder.build();
2071                        } catch (java.text.ParseException e) {
2072                                throw new SerializeException(e.getMessage());
2073                        }
2074                }
2075                
2076                return jwtClaimsSet;
2077        }
2078        
2079        
2080        /**
2081         * Parses an OpenID Connect authentication request from the specified
2082         * URI query parameters.
2083         *
2084         * <p>Example parameters:
2085         *
2086         * <pre>
2087         * response_type = token id_token
2088         * client_id     = s6BhdRkqt3
2089         * redirect_uri  = https://client.example.com/cb
2090         * scope         = openid profile
2091         * state         = af0ifjsldkj
2092         * nonce         = -0S6_WzA2Mj
2093         * </pre>
2094         *
2095         * @param params The parameters. Must not be {@code null}.
2096         *
2097         * @return The OpenID Connect authentication request.
2098         *
2099         * @throws ParseException If the parameters couldn't be parsed to an
2100         *                        OpenID Connect authentication request.
2101         */
2102        public static AuthenticationRequest parse(final Map<String,List<String>> params)
2103                throws ParseException {
2104
2105                return parse(null, params);
2106        }
2107
2108
2109        /**
2110         * Parses an OpenID Connect authentication request from the specified
2111         * URI and query parameters.
2112         *
2113         * <p>Example parameters:
2114         *
2115         * <pre>
2116         * response_type = token id_token
2117         * client_id     = s6BhdRkqt3
2118         * redirect_uri  = https://client.example.com/cb
2119         * scope         = openid profile
2120         * state         = af0ifjsldkj
2121         * nonce         = -0S6_WzA2Mj
2122         * </pre>
2123         *
2124         * @param uri    The URI of the OAuth 2.0 authorisation endpoint. May
2125         *               be {@code null} if the {@link #toHTTPRequest} method
2126         *               will not be used.
2127         * @param params The parameters. Must not be {@code null}.
2128         *
2129         * @return The OpenID Connect authentication request.
2130         *
2131         * @throws ParseException If the parameters couldn't be parsed to an
2132         *                        OpenID Connect authentication request.
2133         */
2134        public static AuthenticationRequest parse(final URI uri, final Map<String,List<String>> params)
2135                throws ParseException {
2136
2137                // Parse and validate the core OAuth 2.0 autz request params in 
2138                // the context of OIDC
2139                AuthorizationRequest ar = AuthorizationRequest.parse(uri, params);
2140                
2141                Nonce nonce = Nonce.parse(MultivaluedMapUtils.getFirstValue(params, "nonce"));
2142                
2143                if (! ar.specifiesRequestObject()) {
2144                        
2145                        // Required params if no JAR is present
2146                        
2147                        if (ar.getRedirectionURI() == null) {
2148                                String msg = "Missing redirect_uri parameter";
2149                                throw new ParseException(msg, OAuth2Error.INVALID_REQUEST.appendDescription(": " + msg),
2150                                        ar.getClientID(), null, ar.impliedResponseMode(), ar.getState());
2151                        }
2152                        
2153                        if (ar.getScope() == null) {
2154                                String msg = "Missing scope parameter";
2155                                throw new ParseException(msg, OAuth2Error.INVALID_REQUEST.appendDescription(": " + msg),
2156                                        ar.getClientID(), ar.getRedirectionURI(), ar.impliedResponseMode(), ar.getState());
2157                        }
2158                        
2159                        // Check nonce requirement
2160                        if (nonce == null && Nonce.isRequired(ar.getResponseType())) {
2161                                String msg = "Missing nonce parameter: Required for response_type=" + ar.getResponseType();
2162                                throw new ParseException(msg, OAuth2Error.INVALID_REQUEST.appendDescription(": " + msg),
2163                                        ar.getClientID(), ar.getRedirectionURI(), ar.impliedResponseMode(), ar.getState());
2164                        }
2165                }
2166                
2167                // Check if present (not in JAR)
2168                if (ar.getResponseType() != null) {
2169                        try {
2170                                OIDCResponseTypeValidator.validate(ar.getResponseType());
2171                        } catch (IllegalArgumentException e) {
2172                                String msg = "Unsupported response_type parameter: " + e.getMessage();
2173                                throw new ParseException(msg, OAuth2Error.UNSUPPORTED_RESPONSE_TYPE.appendDescription(": " + msg),
2174                                        ar.getClientID(), ar.getRedirectionURI(), ar.impliedResponseMode(), ar.getState());
2175                        }
2176                }
2177                
2178                // Check if present (not in JAR)
2179                if (ar.getScope() != null && ! ar.getScope().contains(OIDCScopeValue.OPENID)) {
2180                        String msg = "The scope must include an openid value";
2181                        throw new ParseException(msg, OAuth2Error.INVALID_REQUEST.appendDescription(": " + msg),
2182                                                 ar.getClientID(), ar.getRedirectionURI(), ar.impliedResponseMode(), ar.getState());
2183                }
2184                
2185                Display display = null;
2186
2187                if (params.containsKey("display")) {
2188                        try {
2189                                display = Display.parse(MultivaluedMapUtils.getFirstValue(params, "display"));
2190
2191                        } catch (ParseException e) {
2192                                String msg = "Invalid display parameter: " + e.getMessage();
2193                                throw new ParseException(msg, OAuth2Error.INVALID_REQUEST.appendDescription(": " + msg),
2194                                        ar.getClientID(), ar.getRedirectionURI(), ar.impliedResponseMode(), ar.getState(), e);
2195                        }
2196                }
2197
2198
2199                String v = MultivaluedMapUtils.getFirstValue(params, "max_age");
2200
2201                int maxAge = -1;
2202
2203                if (StringUtils.isNotBlank(v)) {
2204
2205                        try {
2206                                maxAge = Integer.parseInt(v);
2207
2208                        } catch (NumberFormatException e) {
2209                                String msg = "Invalid max_age parameter: " + v;
2210                                throw new ParseException(msg, OAuth2Error.INVALID_REQUEST.appendDescription(": " + msg),
2211                                                         ar.getClientID(), ar.getRedirectionURI(), ar.impliedResponseMode(), ar.getState(), e);
2212                        }
2213                }
2214
2215
2216                List<LangTag> uiLocales;
2217                try {
2218                        uiLocales = LangTagUtils.parseLangTagList(MultivaluedMapUtils.getFirstValue(params, "ui_locales"));
2219                } catch (LangTagException e) {
2220                        String msg = "Invalid ui_locales parameter: " + e.getMessage();
2221                        throw new ParseException(msg, OAuth2Error.INVALID_REQUEST.appendDescription(": " + msg),
2222                                ar.getClientID(), ar.getRedirectionURI(), ar.impliedResponseMode(), ar.getState(), e);
2223                }
2224
2225
2226                List<LangTag> claimsLocales;
2227                try {
2228                        claimsLocales = LangTagUtils.parseLangTagList(MultivaluedMapUtils.getFirstValue(params, "claims_locales"));
2229                        
2230                } catch (LangTagException e) {
2231                        String msg = "Invalid claims_locales parameter: " + e.getMessage();
2232                        throw new ParseException(msg, OAuth2Error.INVALID_REQUEST.appendDescription(": " + msg),
2233                                ar.getClientID(), ar.getRedirectionURI(), ar.impliedResponseMode(), ar.getState(), e);
2234                }
2235
2236
2237                v = MultivaluedMapUtils.getFirstValue(params, "id_token_hint");
2238                
2239                JWT idTokenHint = null;
2240                
2241                if (StringUtils.isNotBlank(v)) {
2242                
2243                        try {
2244                                idTokenHint = JWTParser.parse(v);
2245                                
2246                        } catch (java.text.ParseException e) {
2247                                String msg = "Invalid id_token_hint parameter: " + e.getMessage();
2248                                throw new ParseException(msg, OAuth2Error.INVALID_REQUEST.appendDescription(": " + msg),
2249                                                         ar.getClientID(), ar.getRedirectionURI(), ar.impliedResponseMode(), ar.getState(), e);
2250                        }
2251                }
2252
2253                String loginHint = MultivaluedMapUtils.getFirstValue(params, "login_hint");
2254
2255
2256                v = MultivaluedMapUtils.getFirstValue(params, "acr_values");
2257
2258                List<ACR> acrValues = null;
2259
2260                if (StringUtils.isNotBlank(v)) {
2261
2262                        acrValues = new LinkedList<>();
2263
2264                        StringTokenizer st = new StringTokenizer(v, " ");
2265
2266                        while (st.hasMoreTokens()) {
2267
2268                                acrValues.add(new ACR(st.nextToken()));
2269                        }
2270                }
2271
2272
2273                v = MultivaluedMapUtils.getFirstValue(params, "claims");
2274
2275                OIDCClaimsRequest claims = null;
2276
2277                if (StringUtils.isNotBlank(v)) {
2278                        try {
2279                                claims = OIDCClaimsRequest.parse(v);
2280                        } catch (ParseException e) {
2281                                String msg = "Invalid claims parameter: " + e.getMessage();
2282                                throw new ParseException(msg, OAuth2Error.INVALID_REQUEST.appendDescription(": " + msg),
2283                                                         ar.getClientID(), ar.getRedirectionURI(), ar.impliedResponseMode(), ar.getState(), e);
2284                        }
2285                }
2286                
2287                String purpose = MultivaluedMapUtils.getFirstValue(params, "purpose");
2288                
2289                if (purpose != null && (purpose.length() < PURPOSE_MIN_LENGTH || purpose.length() > PURPOSE_MAX_LENGTH)) {
2290                        String msg = "Invalid purpose parameter: Must not be shorter than " + PURPOSE_MIN_LENGTH + " and longer than " + PURPOSE_MAX_LENGTH + " characters";
2291                        throw new ParseException(msg, OAuth2Error.INVALID_REQUEST.appendDescription(": " + msg),
2292                                ar.getClientID(), ar.getRedirectionURI(), ar.impliedResponseMode(), ar.getState());
2293                }
2294                
2295
2296                // Parse additional custom parameters
2297                Map<String,List<String>> customParams = null;
2298
2299                for (Map.Entry<String,List<String>> p: params.entrySet()) {
2300
2301                        if (! REGISTERED_PARAMETER_NAMES.contains(p.getKey())) {
2302                                // We have a custom parameter
2303                                if (customParams == null) {
2304                                        customParams = new HashMap<>();
2305                                }
2306                                customParams.put(p.getKey(), p.getValue());
2307                        }
2308                }
2309
2310
2311                return new AuthenticationRequest(
2312                        uri, ar.getResponseType(), ar.getResponseMode(), ar.getScope(), ar.getClientID(), ar.getRedirectionURI(), ar.getState(), nonce,
2313                        display, ar.getPrompt(), ar.getDPoPJWKThumbprintConfirmation(), ar.getTrustChain(), maxAge, uiLocales, claimsLocales,
2314                        idTokenHint, loginHint, acrValues, claims, purpose,
2315                        ar.getRequestObject(), ar.getRequestURI(),
2316                        ar.getCodeChallenge(), ar.getCodeChallengeMethod(),
2317                        ar.getAuthorizationDetails(),
2318                        ar.getResources(),
2319                        ar.includeGrantedScopes(),
2320                        customParams);
2321        }
2322        
2323        
2324        /**
2325         * Parses an OpenID Connect authentication request from the specified
2326         * URI query string.
2327         *
2328         * <p>Example URI query string:
2329         *
2330         * <pre>
2331         * response_type=token%20id_token
2332         * &amp;client_id=s6BhdRkqt3
2333         * &amp;redirect_uri=https%3A%2F%2Fclient.example.com%2Fcb
2334         * &amp;scope=openid%20profile
2335         * &amp;state=af0ifjsldkj
2336         * &amp;nonce=n-0S6_WzA2Mj
2337         * </pre>
2338         *
2339         * @param query The URI query string. Must not be {@code null}.
2340         *
2341         * @return The OpenID Connect authentication request.
2342         *
2343         * @throws ParseException If the query string couldn't be parsed to an 
2344         *                        OpenID Connect authentication request.
2345         */
2346        public static AuthenticationRequest parse(final String query)
2347                throws ParseException {
2348        
2349                return parse(null, URLUtils.parseParameters(query));
2350        }
2351
2352
2353        /**
2354         * Parses an OpenID Connect authentication request from the specified
2355         * URI query string.
2356         *
2357         * <p>Example URI query string:
2358         *
2359         * <pre>
2360         * response_type=token%20id_token
2361         * &amp;client_id=s6BhdRkqt3
2362         * &amp;redirect_uri=https%3A%2F%2Fclient.example.com%2Fcb
2363         * &amp;scope=openid%20profile
2364         * &amp;state=af0ifjsldkj
2365         * &amp;nonce=n-0S6_WzA2Mj
2366         * </pre>
2367         *
2368         * @param uri   The URI of the OAuth 2.0 authorisation endpoint. May be
2369         *              {@code null} if the {@link #toHTTPRequest} method will
2370         *              not be used.
2371         * @param query The URI query string. Must not be {@code null}.
2372         *
2373         * @return The OpenID Connect authentication request.
2374         *
2375         * @throws ParseException If the query string couldn't be parsed to an
2376         *                        OpenID Connect authentication request.
2377         */
2378        public static AuthenticationRequest parse(final URI uri, final String query)
2379                throws ParseException {
2380
2381                return parse(uri, URLUtils.parseParameters(query));
2382        }
2383
2384
2385        /**
2386         * Parses an OpenID Connect authentication request from the specified
2387         * URI.
2388         *
2389         * <p>Example URI:
2390         *
2391         * <pre>
2392         * https://server.example.com/authorize?
2393         * response_type=token%20id_token
2394         * &amp;client_id=s6BhdRkqt3
2395         * &amp;redirect_uri=https%3A%2F%2Fclient.example.com%2Fcb
2396         * &amp;scope=openid%20profile
2397         * &amp;state=af0ifjsldkj
2398         * &amp;nonce=n-0S6_WzA2Mj
2399         * </pre>
2400         *
2401         * @param uri The URI. Must not be {@code null}.
2402         *
2403         * @return The OpenID Connect authentication request.
2404         *
2405         * @throws ParseException If the query string couldn't be parsed to an
2406         *                        OpenID Connect authentication request.
2407         */
2408        public static AuthenticationRequest parse(final URI uri)
2409                throws ParseException {
2410
2411                return parse(URIUtils.getBaseURI(uri), URLUtils.parseParameters(uri.getRawQuery()));
2412        }
2413        
2414        
2415        /**
2416         * Parses an authentication request from the specified HTTP GET or HTTP
2417         * POST request.
2418         *
2419         * <p>Example HTTP request (GET):
2420         *
2421         * <pre>
2422         * https://server.example.com/op/authorize?
2423         * response_type=code%20id_token
2424         * &amp;client_id=s6BhdRkqt3
2425         * &amp;redirect_uri=https%3A%2F%2Fclient.example.com%2Fcb
2426         * &amp;scope=openid
2427         * &amp;nonce=n-0S6_WzA2Mj
2428         * &amp;state=af0ifjsldkj
2429         * </pre>
2430         *
2431         * @param httpRequest The HTTP request. Must not be {@code null}.
2432         *
2433         * @return The OpenID Connect authentication request.
2434         *
2435         * @throws ParseException If the HTTP request couldn't be parsed to an 
2436         *                        OpenID Connect authentication request.
2437         */
2438        public static AuthenticationRequest parse(final HTTPRequest httpRequest)
2439                throws ParseException {
2440                
2441                String query = httpRequest.getQuery();
2442                
2443                if (query == null)
2444                        throw new ParseException("Missing URI query string");
2445
2446                URI endpointURI = httpRequest.getURI();
2447                
2448                return parse(endpointURI, query);
2449        }
2450}