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.oauth2.sdk.auth;
019
020
021import java.util.Date;
022import java.util.List;
023
024import net.minidev.json.JSONObject;
025
026import com.nimbusds.jwt.JWTClaimsSet;
027import com.nimbusds.oauth2.sdk.ParseException;
028import com.nimbusds.oauth2.sdk.assertions.jwt.JWTAssertionDetails;
029import com.nimbusds.oauth2.sdk.id.*;
030import com.nimbusds.oauth2.sdk.util.JSONObjectUtils;
031
032
033/**
034 * JWT client authentication claims set, serialisable to a JSON object and JWT 
035 * claims set.
036 *
037 * <p>Used for {@link ClientSecretJWT client secret JWT} and
038 * {@link PrivateKeyJWT private key JWT} authentication at the Token endpoint.
039 *
040 * <p>Example client authentication claims set:
041 *
042 * <pre>
043 * {
044 *   "iss" : "https://client.example.com",
045 *   "sub" : "https://client.example.com",
046 *   "aud" : [ "https://idp.example.com/token" ],
047 *   "jti" : "d396036d-c4d9-40d8-8e98-f7e8327002d9",
048 *   "exp" : 1311281970,
049 *   "iat" : 1311280970
050 * }
051 * </pre>
052 *
053 * <p>Example client authentication claims set where the issuer is a 3rd party:
054 *
055 * <pre>
056 * {
057 *   "iss" : "https://sts.example.com",
058 *   "sub" : "https://client.example.com",
059 *   "aud" : [ "https://idp.example.com/token" ],
060 *   "jti" : "d396036d-c4d9-40d8-8e98-f7e8327002d9",
061 *   "exp" : 1311281970,
062 *   "iat" : 1311280970
063 * }
064 * </pre>
065 *
066 * <p>Related specifications:
067 *
068 * <ul>
069 *     <li>OAuth 2.0 (RFC 6749), section 3.2.1.
070 *     <li>JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and
071 *         Authorization Grants (RFC 7523).
072 * </ul>
073 */
074public class JWTAuthenticationClaimsSet extends JWTAssertionDetails {
075
076
077        /**
078         * Creates a new JWT client authentication claims set. The expiration
079         * time (exp) is set to 1 minute from the current system time.
080         * Generates a default identifier (jti) for the JWT. The issued-at
081         * (iat) and not-before (nbf) claims are not set.
082         *
083         * @param clientID The client identifier. Used to specify the issuer
084         *                 and the subject. Must not be {@code null}.
085         * @param aud      The audience identifier, typically the URI of the
086         *                 authorisation server's Token endpoint. Must not be
087         *                 {@code null}.
088         */
089        public JWTAuthenticationClaimsSet(final ClientID clientID,
090                                          final Audience aud) {
091
092                this(clientID, aud.toSingleAudienceList(), new Date(new Date().getTime() + 60_000L), null, null, new JWTID());
093        }
094
095
096        /**
097         * Creates a new JWT client authentication claims set. The expiration
098         * time (exp) is set to 1 minute from the current system time.
099         * Generates a default identifier (jti) for the JWT. The issued-at
100         * (iat) and not-before (nbf) claims are not set.
101         *
102         * @param iss      The issuer. May be different from the client
103         *                 identifier that is used to specify the subject. Must
104         *                 not be {@code null}.
105         * @param clientID The client identifier. Used to specify the issuer
106         *                 and the subject. Must not be {@code null}.
107         * @param aud      The audience identifier, typically the URI of the
108         *                 authorisation server's Token endpoint. Must not be
109         *                 {@code null}.
110         */
111        public JWTAuthenticationClaimsSet(final Issuer iss,
112                                          final ClientID clientID,
113                                          final Audience aud) {
114
115                this(iss, clientID, aud.toSingleAudienceList(), new Date(new Date().getTime() + 60_000L), null, null, new JWTID());
116        }
117
118        
119        /**
120         * Creates a new JWT client authentication claims set.
121         *
122         * @param clientID The client identifier. Used to specify the issuer 
123         *                 and the subject. Must not be {@code null}.
124         * @param aud      The audience, typically including the URI of the
125         *                 authorisation server's Token endpoint. Must not be 
126         *                 {@code null}.
127         * @param exp      The expiration time. Must not be {@code null}.
128         * @param nbf      The time before which the token must not be 
129         *                 accepted for processing, {@code null} if not
130         *                 specified.
131         * @param iat      The time at which the token was issued, 
132         *                 {@code null} if not specified.
133         * @param jti      Unique identifier for the JWT, {@code null} if
134         *                 not specified.
135         */
136        public JWTAuthenticationClaimsSet(final ClientID clientID,
137                                          final List<Audience> aud,
138                                          final Date exp,
139                                          final Date nbf,
140                                          final Date iat,
141                                          final JWTID jti) {
142
143                super(new Issuer(clientID.getValue()), new Subject(clientID.getValue()), aud, exp, nbf, iat, jti, null);
144        }
145
146        
147        /**
148         * Creates a new JWT client authentication claims set.
149         *
150         * @param iss      The issuer. May be different from the client
151         *                 identifier that is used to specify the subject. Must
152         *                 not be {@code null}.
153         * @param clientID The client identifier. Used to specify the subject.
154         *                 Must not be {@code null}.
155         * @param aud      The audience, typically including the URI of the
156         *                 authorisation server's Token endpoint. Must not be
157         *                 {@code null}.
158         * @param exp      The expiration time. Must not be {@code null}.
159         * @param nbf      The time before which the token must not be
160         *                 accepted for processing, {@code null} if not
161         *                 specified.
162         * @param iat      The time at which the token was issued,
163         *                 {@code null} if not specified.
164         * @param jti      Unique identifier for the JWT, {@code null} if
165         *                 not specified.
166         */
167        public JWTAuthenticationClaimsSet(final Issuer iss,
168                                          final ClientID clientID,
169                                          final List<Audience> aud,
170                                          final Date exp,
171                                          final Date nbf,
172                                          final Date iat,
173                                          final JWTID jti) {
174
175                super(iss, new Subject(clientID.getValue()), aud, exp, nbf, iat, jti, null);
176        }
177
178
179        /**
180         * Gets the client identifier. Corresponds to the {@code sub} claim.
181         *
182         * @return The client identifier.
183         */
184        public ClientID getClientID() {
185
186                return new ClientID(getSubject());
187        }
188        
189        /**
190         * Parses a JWT client authentication claims set from the specified 
191         * JSON object.
192         *
193         * @param jsonObject The JSON object. Must not be {@code null}.
194         *
195         * @return The client authentication claims set.
196         *
197         * @throws ParseException If the JSON object couldn't be parsed to a 
198         *                        client authentication claims set.
199         */
200        public static JWTAuthenticationClaimsSet parse(final JSONObject jsonObject)
201                throws ParseException {
202                
203                JWTAssertionDetails assertion = JWTAssertionDetails.parse(jsonObject);
204
205                return new JWTAuthenticationClaimsSet(
206                        assertion.getIssuer(),
207                        new ClientID(assertion.getSubject()),
208                        assertion.getAudience(),
209                        assertion.getExpirationTime(),
210                        assertion.getNotBeforeTime(),
211                        assertion.getIssueTime(),
212                        assertion.getJWTID());
213        }
214
215
216        /**
217         * Parses a JWT client authentication claims set from the specified JWT 
218         * claims set.
219         *
220         * @param jwtClaimsSet The JWT claims set. Must not be {@code null}.
221         *
222         * @return The client authentication claims set.
223         *
224         * @throws ParseException If the JWT claims set couldn't be parsed to a 
225         *                        client authentication claims set.
226         */
227        public static JWTAuthenticationClaimsSet parse(final JWTClaimsSet jwtClaimsSet)
228                throws ParseException {
229                
230                return parse(JSONObjectUtils.toJSONObject(jwtClaimsSet));
231        }
232}