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