001package com.nimbusds.openid.connect.sdk; 002 003 004import java.util.HashMap; 005import java.util.Map; 006 007import net.jcip.annotations.Immutable; 008 009import net.minidev.json.JSONObject; 010 011import com.nimbusds.oauth2.sdk.AccessTokenResponse; 012import com.nimbusds.oauth2.sdk.ParseException; 013import com.nimbusds.oauth2.sdk.http.HTTPResponse; 014import com.nimbusds.openid.connect.sdk.token.OIDCTokens; 015 016 017/** 018 * OpenID Connect token response from the Token endpoint. 019 * 020 * <p>Example HTTP response: 021 * 022 * <pre> 023 * HTTP/1.1 200 OK 024 * Content-Type: application/json 025 * Cache-Control: no-store 026 * Pragma: no-cache 027 * 028 * { 029 * "access_token" : "SlAV32hkKG", 030 * "token_type" : "Bearer", 031 * "refresh_token" : "8xLOxBtZp8", 032 * "expires_in" : 3600, 033 * "id_token" : "eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9zZXJ2Z 034 * XIuZXhhbXBsZS5jb20iLCJ1c2VyX2lkIjoiMjQ4Mjg5NzYxMDAxIiwiYXVkIjoic 035 * zZCaGRSa3F0MyIsIm5vbmNlIjoibi0wUzZfV3pBMk1qIiwiZXhwIjoxMzExMjgxO 036 * TcwLCJpYXQiOjEzMTEyODA5NzB9.RgXxzppVvn1EjUiV3LIZ19SyhdyREe_2jJjW 037 * 5EC8XjNuJfe7Dte8YxRXxssJ67N8MT9mvOI3HOHm4whNx5FCyemyCGyTLHODCeAr 038 * _id029-4JP0KWySoan1jmT7vbGHhu89-l9MTdaEvu7pNZO7DHGwqnMWRe8hdG7jU 039 * ES4w4ReQTygKwXVVOaiGoeUrv6cZdbyOnpGlRlHaiOsv_xMunNVJtn5dLz-0zZwV 040 * ftKVpFuc1pGaVsyZsOtkT32E4c6MDHeCvIDlR5ESC0ct8BLvGJDB5954MjCR4_X2 041 * GAEHonKw4NF8wTmUFvhslYXmjRNFs21Byjn3jNb7lSa3MBfVsw" 042 * } 043 * </pre> 044 * 045 * <p>Related specifications: 046 * 047 * <ul> 048 * <li>OpenID Connect Core 1.0, section 3.1.3.3. 049 * <li>OAuth 2.0 (RFC 6749), sections 4.1.4 and 5.1. 050 * </ul> 051 */ 052@Immutable 053public class OIDCTokenResponse extends AccessTokenResponse { 054 055 056 /** 057 * The OpenID Connect tokens. 058 */ 059 private final OIDCTokens tokens; 060 061 062 /** 063 * Creates a new OpenID Connect access token response. 064 * 065 * @param tokens The OpenID Connect tokens. Must not be {@code null}. 066 */ 067 public OIDCTokenResponse(final OIDCTokens tokens) { 068 069 this(tokens, null); 070 } 071 072 073 /** 074 * Creates a new OpenID Connect access token response. 075 * 076 * @param tokens The OpenID Connect tokens. Must not be 077 * {@code null}. 078 * @param customParams Optional custom parameters, {@code null} if 079 * none. 080 */ 081 public OIDCTokenResponse(final OIDCTokens tokens, 082 final Map<String, Object> customParams) { 083 084 super(tokens, customParams); 085 086 this.tokens = tokens; 087 } 088 089 090 /** 091 * Gets the OpenID Connect tokens. 092 * 093 * @return The OpenID Connect tokens. 094 */ 095 public OIDCTokens getOIDCTokens() { 096 097 return tokens; 098 } 099 100 101 /** 102 * Returns a JSON object representation of this OpenID Connect token 103 * response. 104 * 105 * <p>Example JSON object: 106 * 107 * <pre> 108 * { 109 * "access_token" : "SlAV32hkKG", 110 * "token_type" : "Bearer", 111 * "refresh_token": "8xLOxBtZp8", 112 * "expires_in" : 3600, 113 * "id_token" : "eyJ0 ... NiJ9.eyJ1c ... I6IjIifX0.DeWt4Qu ... ZXso" 114 * } 115 * </pre> 116 * 117 * @return The JSON object. 118 */ 119 @Override 120 public JSONObject toJSONObject() { 121 122 JSONObject o = super.toJSONObject(); 123 o.put("id_token", getOIDCTokens().getIDTokenString()); 124 return o; 125 } 126 127 128 /** 129 * Parses an OpenID Connect token response from the specified JSON 130 * object. 131 * 132 * @param jsonObject The JSON object to parse. Must not be 133 * {@code null}. 134 * 135 * @return The OpenID Connect token response. 136 * 137 * @throws ParseException If the JSON object couldn't be parsed to an 138 * OpenID Connect token response. 139 */ 140 public static OIDCTokenResponse parse(final JSONObject jsonObject) 141 throws ParseException { 142 143 OIDCTokens tokens = OIDCTokens.parse(jsonObject); 144 145 // Parse the custom parameters 146 Map<String,Object> customParams = new HashMap<>(); 147 customParams.putAll(jsonObject); 148 for (String tokenParam: tokens.getParameterNames()) { 149 customParams.remove(tokenParam); 150 } 151 152 if (customParams.isEmpty()) { 153 return new OIDCTokenResponse(tokens); 154 } 155 156 return new OIDCTokenResponse(tokens, customParams); 157 } 158 159 160 /** 161 * Parses an OpenID Connect access token response from the specified 162 * HTTP response. 163 * 164 * @param httpResponse The HTTP response. Must not be {@code null}. 165 * 166 * @return The OpenID Connect access token response. 167 * 168 * @throws ParseException If the HTTP response couldn't be parsed to an 169 * OpenID Connect access token response. 170 */ 171 public static OIDCTokenResponse parse(final HTTPResponse httpResponse) 172 throws ParseException { 173 174 httpResponse.ensureStatusCode(HTTPResponse.SC_OK); 175 JSONObject jsonObject = httpResponse.getContentAsJSONObject(); 176 return parse(jsonObject); 177 } 178}