001package com.nimbusds.oauth2.sdk; 002 003 004import net.jcip.annotations.Immutable; 005 006import net.minidev.json.JSONObject; 007 008import com.nimbusds.oauth2.sdk.token.AccessToken; 009import com.nimbusds.oauth2.sdk.token.RefreshToken; 010import com.nimbusds.oauth2.sdk.token.TokenPair; 011import com.nimbusds.oauth2.sdk.http.CommonContentTypes; 012import com.nimbusds.oauth2.sdk.http.HTTPResponse; 013 014 015/** 016 * Access token response from the Token endpoint. 017 * 018 * <p>Example HTTP response: 019 * 020 * <pre> 021 * HTTP/1.1 200 OK 022 * Content-Type: application/json;charset=UTF-8 023 * Cache-Control: no-store 024 * Pragma: no-cache 025 * 026 * { 027 * "access_token" : "2YotnFZFEjr1zCsicMWpAA", 028 * "token_type" : "example", 029 * "expires_in" : 3600, 030 * "refresh_token" : "tGzv3JOkF0XG5Qx2TlKWIA", 031 * "example_parameter" : "example_value" 032 * } 033 * </pre> 034 * 035 * <p>Related specifications: 036 * 037 * <ul> 038 * <li>OAuth 2.0 (RFC 6749), sections 4.1.4, 4.3.3, 4.4.3 and 5.1. 039 * </ul> 040 */ 041@Immutable 042public class AccessTokenResponse 043 extends TokenResponse 044 implements SuccessResponse { 045 046 047 /** 048 * The access token. 049 */ 050 private final AccessToken accessToken; 051 052 053 /** 054 * Optional refresh token. 055 */ 056 private final RefreshToken refreshToken; 057 058 059 /** 060 * Creates a new access token response. 061 * 062 * @param accessToken The access token. Must not be {@code null}. 063 * @param refreshToken Optional refresh token, {@code null} if none. 064 */ 065 public AccessTokenResponse(final AccessToken accessToken, 066 final RefreshToken refreshToken) { 067 068 if (accessToken == null) 069 throw new IllegalArgumentException("The access token must not be null"); 070 071 this.accessToken = accessToken; 072 073 this.refreshToken = refreshToken; 074 } 075 076 077 /** 078 * Creates a new access token response. 079 * 080 * @param tokenPair The access and refresh token pair. Must not be 081 * {@code null}. 082 */ 083 public AccessTokenResponse(final TokenPair tokenPair) { 084 085 this(tokenPair.getAccessToken(), tokenPair.getRefreshToken()); 086 } 087 088 089 /** 090 * Gets the access token. 091 * 092 * @return The access token. 093 */ 094 public AccessToken getAccessToken() { 095 096 return accessToken; 097 } 098 099 100 /** 101 * Gets the optional refresh token. 102 * 103 * @return The refresh token, {@code null} if none. 104 */ 105 public RefreshToken getRefreshToken() { 106 107 return refreshToken; 108 } 109 110 111 /** 112 * Gets the access and refresh token pair. 113 * 114 * @return The access and refresh token pair. Must not be {@code null}. 115 */ 116 public TokenPair getTokenPair() { 117 118 return new TokenPair(accessToken, refreshToken); 119 } 120 121 122 /** 123 * Returns the JSON object representing this access token response. 124 * 125 * <p>Example JSON object: 126 * 127 * <pre> 128 * { 129 * "access_token" : "SlAV32hkKG", 130 * "token_type" : "Bearer", 131 * "refresh_token": "8xLOxBtZp8", 132 * "expires_in" : 3600 133 * } 134 * </pre> 135 * 136 * @return The JSON object. 137 * 138 * @throws SerializeException If this access token response couldn't be 139 * serialised to a JSON object. 140 */ 141 public JSONObject toJSONObject() 142 throws SerializeException { 143 144 JSONObject o = accessToken.toJSONObject(); 145 146 if (refreshToken != null) 147 o.putAll(refreshToken.toJSONObject()); 148 149 return o; 150 } 151 152 153 @Override 154 public HTTPResponse toHTTPResponse() 155 throws SerializeException { 156 157 HTTPResponse httpResponse = new HTTPResponse(HTTPResponse.SC_OK); 158 159 httpResponse.setContentType(CommonContentTypes.APPLICATION_JSON); 160 httpResponse.setCacheControl("no-store"); 161 httpResponse.setPragma("no-cache"); 162 163 httpResponse.setContent(toJSONObject().toString()); 164 165 return httpResponse; 166 } 167 168 169 /** 170 * Parses an access token response from the specified JSON object. 171 * 172 * @param jsonObject The JSON object to parse. Must not be {@code null}. 173 * 174 * @return The access token response. 175 * 176 * @throws ParseException If the JSON object couldn't be parsed to an 177 * access token response. 178 */ 179 public static AccessTokenResponse parse(final JSONObject jsonObject) 180 throws ParseException { 181 182 AccessToken accessToken = AccessToken.parse(jsonObject); 183 184 RefreshToken refreshToken = RefreshToken.parse(jsonObject); 185 186 return new AccessTokenResponse(accessToken, refreshToken); 187 } 188 189 190 /** 191 * Parses an access token response from the specified HTTP response. 192 * 193 * @param httpResponse The HTTP response. Must not be {@code null}. 194 * 195 * @return The access token response. 196 * 197 * @throws ParseException If the HTTP response couldn't be parsed to an 198 * access token response. 199 */ 200 public static AccessTokenResponse parse(final HTTPResponse httpResponse) 201 throws ParseException { 202 203 httpResponse.ensureStatusCode(HTTPResponse.SC_OK); 204 205 JSONObject jsonObject = httpResponse.getContentAsJSONObject(); 206 207 return parse(jsonObject); 208 } 209}