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 refreshToken The refresh token. Must not be {@code null}. 057 */ 058 public RefreshTokenRequest(final RefreshToken refreshToken) { 059 060 this(refreshToken, null); 061 } 062 063 064 /** 065 * Creates a new authenticated refresh token request. 066 * 067 * @param refreshToken The refresh token. Must not be {@code null}. 068 * @param clientAuth The client authentication, {@code null} if none. 069 */ 070 public RefreshTokenRequest(final RefreshToken refreshToken, 071 final ClientAuthentication clientAuth) { 072 073 super(GrantType.REFRESH_TOKEN, clientAuth); 074 075 if (refreshToken == null) 076 throw new IllegalArgumentException("The refresh token must not be null"); 077 078 this.refreshToken = refreshToken; 079 } 080 081 082 /** 083 * Gets the refresh token. 084 * 085 * @return The refresh token. 086 */ 087 public RefreshToken getRefreshToken() { 088 089 return refreshToken; 090 } 091 092 093 @Override 094 public HTTPRequest toHTTPRequest(final URL url) 095 throws SerializeException { 096 097 HTTPRequest httpRequest = new HTTPRequest(HTTPRequest.Method.POST, url); 098 099 httpRequest.setContentType(CommonContentTypes.APPLICATION_URLENCODED); 100 101 Map<String,String> params = new LinkedHashMap<String,String>(); 102 params.put("grant_type", getGrantType().toString()); 103 params.put("refresh_token", refreshToken.getValue()); 104 105 httpRequest.setQuery(URLUtils.serializeParameters(params)); 106 107 if (getClientAuthentication() != null) 108 getClientAuthentication().applyTo(httpRequest); 109 110 return httpRequest; 111 } 112 113 114 /** 115 * Parses the specified HTTP request for a refresh token request. 116 * 117 * @param httpRequest The HTTP request. Must not be {@code null}. 118 * 119 * @return The refresh token request. 120 * 121 * @throws ParseException If the HTTP request couldn't be parsed to a 122 * refresh token request. 123 */ 124 public static RefreshTokenRequest parse(final HTTPRequest httpRequest) 125 throws ParseException { 126 127 // Only HTTP POST accepted 128 httpRequest.ensureMethod(HTTPRequest.Method.POST); 129 httpRequest.ensureContentType(CommonContentTypes.APPLICATION_URLENCODED); 130 131 // No fragment! 132 // May use query component! 133 134 Map<String,String> params = httpRequest.getQueryParameters(); 135 136 137 // Parse grant type 138 String grantTypeString = params.get("grant_type"); 139 140 if (grantTypeString == null) 141 throw new ParseException("Missing \"grant_type\" parameter"); 142 143 GrantType grantType = new GrantType(grantTypeString); 144 145 if (! grantType.equals(GrantType.REFRESH_TOKEN)) 146 throw new ParseException("Invalid \"grant_type\" parameter: " + grantTypeString); 147 148 149 // Parse refresh token 150 String tokenString = params.get("refresh_token"); 151 152 if (tokenString == null) 153 throw new ParseException("Missing \"refresh_token\" parameter"); 154 155 // Parse client authentication 156 ClientAuthentication clientAuth = ClientAuthentication.parse(httpRequest); 157 158 return new RefreshTokenRequest(new RefreshToken(tokenString), clientAuth); 159 } 160 }