001package com.nimbusds.oauth2.sdk; 002 003 004import java.net.URL; 005import java.util.LinkedHashMap; 006import java.util.Map; 007 008import com.nimbusds.oauth2.sdk.auth.ClientAuthentication; 009import com.nimbusds.oauth2.sdk.http.CommonContentTypes; 010import com.nimbusds.oauth2.sdk.http.HTTPRequest; 011import com.nimbusds.oauth2.sdk.util.URLUtils; 012 013 014/** 015 * Token request. Used to obtain an 016 * {@link com.nimbusds.oauth2.sdk.token.AccessToken access token} and an 017 * optional {@link com.nimbusds.oauth2.sdk.token.RefreshToken refresh token} 018 * at the Token endpoint of the authorisation server. This class is immutable. 019 * 020 * <p>Example token request with an authorisation code grant: 021 * 022 * <pre> 023 * POST /token HTTP/1.1 024 * Host: server.example.com 025 * Content-Type: application/x-www-form-urlencoded 026 * Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW 027 * 028 * grant_type=authorization_code 029 * &code=SplxlOBeZQQYbYS6WxSbIA 030 * &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb 031 * </pre> 032 * 033 * <p>Related specifications: 034 * 035 * <ul> 036 * <li>OAuth 2.0 (RFC 6749), sections 4.1.3, 4.3.2, 4.4.2 and 6. 037 * </ul> 038 * 039 * @author Vladimir Dzhuvinov 040 */ 041public class TokenRequest extends AbstractRequest { 042 043 044 /** 045 * The client authentication, {@code null} if none. 046 */ 047 private final ClientAuthentication clientAuth; 048 049 050 /** 051 * The authorisation grant. 052 */ 053 private final AuthorizationGrant authzGrant; 054 055 056 /** 057 * Creates a new token request. 058 * 059 * @param uri The URI of the token endpoint. May be 060 * {@code null} if the {@link #toHTTPRequest()} 061 * method will not be used. 062 * @param clientAuth The client authentication, {@code null} if none. 063 * @param authzGrant The authorisation grant. Must not be {@code null}. 064 */ 065 public TokenRequest(final URL uri, 066 final ClientAuthentication clientAuth, 067 final AuthorizationGrant authzGrant) { 068 069 super(uri); 070 071 this.clientAuth = clientAuth; 072 073 if (authzGrant == null) 074 throw new IllegalArgumentException("The authorization grant must not be null"); 075 076 this.authzGrant = authzGrant; 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 * Gets the authorisation grant. 093 * 094 * @return The authorisation grant. 095 */ 096 public AuthorizationGrant getAuthorizationGrant() { 097 098 return authzGrant; 099 } 100 101 102 @Override 103 public HTTPRequest toHTTPRequest() 104 throws SerializeException { 105 106 if (getURI() == null) 107 throw new SerializeException("The endpoint URI is not specified"); 108 109 HTTPRequest httpRequest = new HTTPRequest(HTTPRequest.Method.POST, getURI()); 110 httpRequest.setContentType(CommonContentTypes.APPLICATION_URLENCODED); 111 112 Map<String,String> params = authzGrant.toParameters(); 113 114 httpRequest.setQuery(URLUtils.serializeParameters(params)); 115 116 if (getClientAuthentication() != null) 117 getClientAuthentication().applyTo(httpRequest); 118 119 return httpRequest; 120 } 121 122 123 /** 124 * Parses the specified HTTP request for a token request. 125 * 126 * @param httpRequest The HTTP request. Must not be {@code null}. 127 * 128 * @return The token request. 129 * 130 * @throws ParseException If the HTTP request couldn't be parsed to a 131 * token request. 132 */ 133 public static TokenRequest parse(final HTTPRequest httpRequest) 134 throws ParseException { 135 136 // Only HTTP POST accepted 137 httpRequest.ensureMethod(HTTPRequest.Method.POST); 138 httpRequest.ensureContentType(CommonContentTypes.APPLICATION_URLENCODED); 139 140 // No fragment! 141 // May use query component! 142 Map<String,String> params = httpRequest.getQueryParameters(); 143 144 // Parse grant 145 AuthorizationGrant authzGrant = AuthorizationGrant.parse(params); 146 147 // Parse client auth 148 ClientAuthentication clientAuth = ClientAuthentication.parse(httpRequest); 149 150 return new TokenRequest(httpRequest.getURL(), clientAuth, authzGrant); 151 } 152}