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