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