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