001 package com.nimbusds.oauth2.sdk; 002 003 004 import java.util.Map; 005 006 import com.nimbusds.oauth2.sdk.auth.ClientAuthentication; 007 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 * @version $version$ (2013-01-30) 038 */ 039 public abstract class TokenRequest implements Request { 040 041 042 /** 043 * The grant type. 044 */ 045 private final GrantType grantType; 046 047 048 /** 049 * The client authentication, {@code null} if none. 050 */ 051 private final ClientAuthentication clientAuth; 052 053 054 /** 055 * Creates a new token request. 056 * 057 * @param grantType The grant type. Must not be {@code null}. 058 * @param clientAuth The client authentication, {@code null} if none. 059 */ 060 protected TokenRequest(final GrantType grantType, final ClientAuthentication clientAuth) { 061 062 if (grantType == null) 063 throw new IllegalArgumentException("The grant type must not be null"); 064 065 this.grantType = grantType; 066 067 this.clientAuth = clientAuth; 068 } 069 070 071 /** 072 * Gets the grant type. 073 * 074 * @return The grant type. 075 */ 076 public GrantType getGrantType() { 077 078 return grantType; 079 } 080 081 082 /** 083 * Gets the client authentication. 084 * 085 * @return The client authentication, {@code null} if none. 086 */ 087 public ClientAuthentication getClientAuthentication() { 088 089 return clientAuth; 090 } 091 092 093 /** 094 * Parses the specified HTTP request for a token request. 095 * 096 * @param httpRequest The HTTP request. Must not be {@code null}. 097 * 098 * @return The token request. 099 * 100 * @throws ParseException If the HTTP request couldn't be parsed to a 101 * token request. 102 */ 103 public static TokenRequest parse(final HTTPRequest httpRequest) 104 throws ParseException { 105 106 // Only HTTP POST accepted 107 httpRequest.ensureMethod(HTTPRequest.Method.POST); 108 httpRequest.ensureContentType(CommonContentTypes.APPLICATION_URLENCODED); 109 110 // No fragment! 111 // May use query component! 112 Map<String,String> params = httpRequest.getQueryParameters(); 113 114 115 // Parse grant type 116 final String grantTypeString = params.get("grant_type"); 117 118 if (grantTypeString == null) 119 throw new ParseException("Missing \"grant_type\" parameter"); 120 121 GrantType grantType = new GrantType(grantTypeString); 122 123 if (grantType.equals(GrantType.AUTHORIZATION_CODE)) 124 return AccessTokenRequest.parse(httpRequest); 125 126 else if (grantType.equals(GrantType.REFRESH_TOKEN)) 127 return RefreshTokenRequest.parse(httpRequest); 128 129 else 130 throw new ParseException("Unsupported \"grant_type\": " + grantType); 131 } 132 }