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