001 package com.nimbusds.oauth2.sdk; 002 003 004 import java.net.URL; 005 import java.util.LinkedHashMap; 006 import java.util.Map; 007 008 import net.jcip.annotations.Immutable; 009 010 import com.nimbusds.oauth2.sdk.auth.ClientAuthentication; 011 import com.nimbusds.oauth2.sdk.token.RefreshToken; 012 import com.nimbusds.oauth2.sdk.http.CommonContentTypes; 013 import com.nimbusds.oauth2.sdk.http.HTTPRequest; 014 import com.nimbusds.oauth2.sdk.util.URLUtils; 015 016 017 /** 018 * Refresh token request to the Token endpoint. Used to refresh an 019 * {@link com.nimbusds.oauth2.sdk.token.AccessToken access token}. This class 020 * is immutable. 021 * 022 * <p>Note that the optional scope parameter is not supported. 023 * 024 * <p>Example refresh token request: 025 * 026 * <pre> 027 * POST /token HTTP/1.1 028 * Host: server.example.com 029 * Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW 030 * Content-Type: application/x-www-form-urlencoded;charset=UTF-8 031 * 032 * grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA 033 * </pre> 034 * 035 * <p>Related specifications: 036 * 037 * <ul> 038 * <li>OAuth 2.0 (RFC 6749), section 6. 039 * </ul> 040 * 041 * @author Vladimir Dzhuvinov 042 */ 043 @Immutable 044 public final class RefreshTokenRequest extends TokenRequest { 045 046 047 /** 048 * The refresh token. 049 */ 050 private final RefreshToken refreshToken; 051 052 053 /** 054 * Creates a new unauthenticated refresh token request. 055 * 056 * @param uri The URI of the token endpoint. May be 057 * {@code null} if the {@link #toHTTPRequest()} 058 * method will not be used. 059 * @param refreshToken The refresh token. Must not be {@code null}. 060 */ 061 public RefreshTokenRequest(final URL uri, final RefreshToken refreshToken) { 062 063 this(uri, refreshToken, null); 064 } 065 066 067 /** 068 * Creates a new authenticated refresh token request. 069 * 070 * @param uri The URI of the token endpoint. May be 071 * {@code null} if the {@link #toHTTPRequest()} 072 * method will not be used. 073 * @param refreshToken The refresh token. Must not be {@code null}. 074 * @param clientAuth The client authentication, {@code null} if none. 075 */ 076 public RefreshTokenRequest(final URL uri, 077 final RefreshToken refreshToken, 078 final ClientAuthentication clientAuth) { 079 080 super(uri, GrantType.REFRESH_TOKEN, clientAuth); 081 082 if (refreshToken == null) 083 throw new IllegalArgumentException("The refresh token must not be null"); 084 085 this.refreshToken = refreshToken; 086 } 087 088 089 /** 090 * Gets the refresh token. 091 * 092 * @return The refresh token. 093 */ 094 public RefreshToken getRefreshToken() { 095 096 return refreshToken; 097 } 098 099 100 @Override 101 public HTTPRequest toHTTPRequest() 102 throws SerializeException { 103 104 if (getURI() == null) 105 throw new SerializeException("The endpoint URI is not specified"); 106 107 HTTPRequest httpRequest = new HTTPRequest(HTTPRequest.Method.POST, getURI()); 108 109 httpRequest.setContentType(CommonContentTypes.APPLICATION_URLENCODED); 110 111 Map<String,String> params = new LinkedHashMap<String,String>(); 112 params.put("grant_type", getGrantType().toString()); 113 params.put("refresh_token", refreshToken.getValue()); 114 115 httpRequest.setQuery(URLUtils.serializeParameters(params)); 116 117 if (getClientAuthentication() != null) 118 getClientAuthentication().applyTo(httpRequest); 119 120 return httpRequest; 121 } 122 123 124 /** 125 * Parses the specified HTTP request for a refresh token request. 126 * 127 * @param httpRequest The HTTP request. Must not be {@code null}. 128 * 129 * @return The refresh token request. 130 * 131 * @throws ParseException If the HTTP request couldn't be parsed to a 132 * refresh token request. 133 */ 134 public static RefreshTokenRequest parse(final HTTPRequest httpRequest) 135 throws ParseException { 136 137 // Only HTTP POST accepted 138 httpRequest.ensureMethod(HTTPRequest.Method.POST); 139 httpRequest.ensureContentType(CommonContentTypes.APPLICATION_URLENCODED); 140 141 // No fragment! 142 // May use query component! 143 144 Map<String,String> params = httpRequest.getQueryParameters(); 145 146 147 // Parse grant type 148 String grantTypeString = params.get("grant_type"); 149 150 if (grantTypeString == null) 151 throw new ParseException("Missing \"grant_type\" parameter"); 152 153 GrantType grantType = new GrantType(grantTypeString); 154 155 if (! grantType.equals(GrantType.REFRESH_TOKEN)) 156 throw new ParseException("Invalid \"grant_type\" parameter: " + grantTypeString); 157 158 159 // Parse refresh token 160 String tokenString = params.get("refresh_token"); 161 162 if (tokenString == null) 163 throw new ParseException("Missing \"refresh_token\" parameter"); 164 165 // Parse client authentication 166 ClientAuthentication clientAuth = ClientAuthentication.parse(httpRequest); 167 168 return new RefreshTokenRequest(URLUtils.getBaseURL(httpRequest.getURL()), 169 new RefreshToken(tokenString), clientAuth); 170 } 171 }