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://server.c2id.com",
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://server.c2id.com",
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, typically the authorisation server
085         *                 issuer URI. Must not be {@code null}.
086         */
087        public JWTAuthenticationClaimsSet(final ClientID clientID,
088                                          final Audience aud) {
089
090                this(clientID, aud.toSingleAudienceList(), new Date(new Date().getTime() + 60_000L), null, null, new JWTID());
091        }
092
093
094        /**
095         * Creates a new JWT client authentication claims set. The expiration
096         * time (exp) is set to 1 minute from the current system time.
097         * Generates a default identifier (jti) for the JWT. The issued-at
098         * (iat) and not-before (nbf) claims are not set.
099         *
100         * @param iss      The issuer. May be different from the client
101         *                 identifier that is used to specify the subject. Must
102         *                 not be {@code null}.
103         * @param clientID The client identifier. Used to specify the issuer
104         *                 and the subject. Must not be {@code null}.
105         * @param aud      The audience, typically the authorisation server
106         *                 issuer URI. Must not be {@code null}.
107         */
108        public JWTAuthenticationClaimsSet(final Issuer iss,
109                                          final ClientID clientID,
110                                          final Audience aud) {
111
112                this(iss, clientID, aud.toSingleAudienceList(), new Date(new Date().getTime() + 60_000L), null, null, new JWTID());
113        }
114
115        
116        /**
117         * Creates a new JWT client authentication claims set.
118         *
119         * @param clientID The client identifier. Used to specify the issuer 
120         *                 and the subject. Must not be {@code null}.
121         * @param aud      The audience, typically a singleton list with the
122         *                 authorisation server issuer URI. Must not be
123         *                 {@code null}.
124         * @param exp      The expiration time. Must not be {@code null}.
125         * @param nbf      The time before which the token must not be 
126         *                 accepted for processing, {@code null} if not
127         *                 specified.
128         * @param iat      The time at which the token was issued, 
129         *                 {@code null} if not specified.
130         * @param jti      Unique identifier for the JWT, {@code null} if
131         *                 not specified.
132         */
133        public JWTAuthenticationClaimsSet(final ClientID clientID,
134                                          final List<Audience> aud,
135                                          final Date exp,
136                                          final Date nbf,
137                                          final Date iat,
138                                          final JWTID jti) {
139
140                super(new Issuer(clientID.getValue()), new Subject(clientID.getValue()), aud, exp, nbf, iat, jti, null);
141        }
142
143        
144        /**
145         * Creates a new JWT client authentication claims set.
146         *
147         * @param iss      The issuer. May be different from the client
148         *                 identifier that is used to specify the subject. Must
149         *                 not be {@code null}.
150         * @param clientID The client identifier. Used to specify the subject.
151         *                 Must not be {@code null}.
152         * @param aud      The audience, typically a singleton list with the
153         *                 authorisation server issuer URI. Must not be
154         *                 {@code null}.
155         * @param exp      The expiration time. Must not be {@code null}.
156         * @param nbf      The time before which the token must not be
157         *                 accepted for processing, {@code null} if not
158         *                 specified.
159         * @param iat      The time at which the token was issued,
160         *                 {@code null} if not specified.
161         * @param jti      Unique identifier for the JWT, {@code null} if
162         *                 not specified.
163         */
164        public JWTAuthenticationClaimsSet(final Issuer iss,
165                                          final ClientID clientID,
166                                          final List<Audience> aud,
167                                          final Date exp,
168                                          final Date nbf,
169                                          final Date iat,
170                                          final JWTID jti) {
171
172                super(iss, new Subject(clientID.getValue()), aud, exp, nbf, iat, jti, null);
173        }
174
175
176        /**
177         * Gets the client identifier. Corresponds to the {@code sub} claim.
178         *
179         * @return The client identifier.
180         */
181        public ClientID getClientID() {
182
183                return new ClientID(getSubject());
184        }
185        
186        /**
187         * Parses a JWT client authentication claims set from the specified 
188         * JSON object.
189         *
190         * @param jsonObject The JSON object. Must not be {@code null}.
191         *
192         * @return The client authentication claims set.
193         *
194         * @throws ParseException If the JSON object couldn't be parsed to a 
195         *                        client authentication claims set.
196         */
197        public static JWTAuthenticationClaimsSet parse(final JSONObject jsonObject)
198                throws ParseException {
199                
200                JWTAssertionDetails assertion = JWTAssertionDetails.parse(jsonObject);
201
202                return new JWTAuthenticationClaimsSet(
203                        assertion.getIssuer(),
204                        new ClientID(assertion.getSubject()),
205                        assertion.getAudience(),
206                        assertion.getExpirationTime(),
207                        assertion.getNotBeforeTime(),
208                        assertion.getIssueTime(),
209                        assertion.getJWTID());
210        }
211
212
213        /**
214         * Parses a JWT client authentication claims set from the specified JWT 
215         * claims set.
216         *
217         * @param jwtClaimsSet The JWT claims set. Must not be {@code null}.
218         *
219         * @return The client authentication claims set.
220         *
221         * @throws ParseException If the JWT claims set couldn't be parsed to a 
222         *                        client authentication claims set.
223         */
224        public static JWTAuthenticationClaimsSet parse(final JWTClaimsSet jwtClaimsSet)
225                throws ParseException {
226                
227                return parse(JSONObjectUtils.toJSONObject(jwtClaimsSet));
228        }
229}