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