001 package com.nimbusds.oauth2.sdk; 002 003 004 import java.net.URL; 005 import java.util.Map; 006 007 import com.nimbusds.oauth2.sdk.auth.ClientAuthentication; 008 import com.nimbusds.oauth2.sdk.http.CommonContentTypes; 009 import com.nimbusds.oauth2.sdk.http.HTTPRequest; 010 011 012 /** 013 * The base abstract class for access token and refresh token requests to the 014 * Token endpoint. The request type can be inferred by calling 015 * {@link #getGrantType}. 016 * 017 * <p>Example access token request: 018 * 019 * <pre> 020 * POST /token HTTP/1.1 021 * Host: server.example.com 022 * Content-Type: application/x-www-form-urlencoded 023 * Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW 024 * 025 * grant_type=authorization_code 026 * &code=SplxlOBeZQQYbYS6WxSbIA 027 * &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb 028 * </pre> 029 * 030 * <p>Related specifications: 031 * 032 * <ul> 033 * <li>OAuth 2.0 (RFC 6749), sections 4.1.3, . 034 * </ul> 035 * 036 * @author Vladimir Dzhuvinov 037 */ 038 public abstract class TokenRequest extends AbstractRequest { 039 040 041 /** 042 * The grant type. 043 */ 044 private final GrantType grantType; 045 046 047 /** 048 * The client authentication, {@code null} if none. 049 */ 050 private final ClientAuthentication clientAuth; 051 052 053 /** 054 * Creates a new 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 grantType The grant type. Must not be {@code null}. 060 * @param clientAuth The client authentication, {@code null} if none. 061 */ 062 protected TokenRequest(final URL uri, 063 final GrantType grantType, 064 final ClientAuthentication clientAuth) { 065 066 super(uri); 067 068 if (grantType == null) 069 throw new IllegalArgumentException("The grant type must not be null"); 070 071 this.grantType = grantType; 072 073 this.clientAuth = clientAuth; 074 } 075 076 077 /** 078 * Gets the grant type. 079 * 080 * @return The grant type. 081 */ 082 public GrantType getGrantType() { 083 084 return grantType; 085 } 086 087 088 /** 089 * Gets the client authentication. 090 * 091 * @return The client authentication, {@code null} if none. 092 */ 093 public ClientAuthentication getClientAuthentication() { 094 095 return clientAuth; 096 } 097 098 099 /** 100 * Parses the specified HTTP request for a token request. 101 * 102 * @param httpRequest The HTTP request. Must not be {@code null}. 103 * 104 * @return The token request. 105 * 106 * @throws ParseException If the HTTP request couldn't be parsed to a 107 * token request. 108 */ 109 public static TokenRequest parse(final HTTPRequest httpRequest) 110 throws ParseException { 111 112 // Only HTTP POST accepted 113 httpRequest.ensureMethod(HTTPRequest.Method.POST); 114 httpRequest.ensureContentType(CommonContentTypes.APPLICATION_URLENCODED); 115 116 // No fragment! 117 // May use query component! 118 Map<String,String> params = httpRequest.getQueryParameters(); 119 120 121 // Parse grant type 122 final String grantTypeString = params.get("grant_type"); 123 124 if (grantTypeString == null) 125 throw new ParseException("Missing \"grant_type\" parameter"); 126 127 GrantType grantType = new GrantType(grantTypeString); 128 129 if (grantType.equals(GrantType.AUTHORIZATION_CODE)) 130 return AccessTokenRequest.parse(httpRequest); 131 132 else if (grantType.equals(GrantType.REFRESH_TOKEN)) 133 return RefreshTokenRequest.parse(httpRequest); 134 135 else 136 throw new ParseException("Unsupported \"grant_type\": " + grantType); 137 } 138 }