001package com.nimbusds.oauth2.sdk; 002 003 004import java.net.URL; 005import java.util.Map; 006 007import net.jcip.annotations.Immutable; 008 009import com.nimbusds.oauth2.sdk.auth.ClientAuthentication; 010import com.nimbusds.oauth2.sdk.http.CommonContentTypes; 011import com.nimbusds.oauth2.sdk.http.HTTPRequest; 012import com.nimbusds.oauth2.sdk.util.URLUtils; 013 014 015/** 016 * Token request. Used to obtain an 017 * {@link com.nimbusds.oauth2.sdk.token.AccessToken access token} and an 018 * optional {@link com.nimbusds.oauth2.sdk.token.RefreshToken refresh token} 019 * at the Token endpoint of the authorisation server. 020 * 021 * <p>Example token request with an authorisation code grant: 022 * 023 * <pre> 024 * POST /token HTTP/1.1 025 * Host: server.example.com 026 * Content-Type: application/x-www-form-urlencoded 027 * Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW 028 * 029 * grant_type=authorization_code 030 * &code=SplxlOBeZQQYbYS6WxSbIA 031 * &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb 032 * </pre> 033 * 034 * <p>Related specifications: 035 * 036 * <ul> 037 * <li>OAuth 2.0 (RFC 6749), sections 4.1.3, 4.3.2, 4.4.2 and 6. 038 * </ul> 039 */ 040@Immutable 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} method 061 * 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 (getEndpointURI() == null) 107 throw new SerializeException("The endpoint URI is not specified"); 108 109 HTTPRequest httpRequest = new HTTPRequest(HTTPRequest.Method.POST, getEndpointURI()); 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}