}
// If the HTTP request was not a valid OAuth token request, then we
// have no other choice but to reject it as a bad request.
catch(OAuthProblemException e) {
// Build the OAuth response.
OAuthResponse oauthResponse =
OAuthResponse
.errorResponse(HttpServletResponse.SC_BAD_REQUEST)
.error(e)
.buildJSONMessage();
// Set the HTTP response status code from the OAuth response.
response.setStatus(oauthResponse.getResponseStatus());
// Return the error message.
return oauthResponse.getBody();
}
// Attempt to get the client.
ThirdParty thirdParty =
ThirdPartyBin
.getInstance().getThirdParty(oauthRequest.getClientId());
// If the client is unknown, respond as such.
if(thirdParty == null) {
// Create the OAuth response.
OAuthResponse oauthResponse =
OAuthASResponse
.errorResponse(HttpServletResponse.SC_BAD_REQUEST)
.setError(TokenResponse.INVALID_CLIENT)
.setErrorDescription(
"The client is unknown: " + oauthRequest.getClientId())
.buildJSONMessage();
// Set the status and return the error message.
response.setStatus(oauthResponse.getResponseStatus());
return oauthResponse.getBody();
}
// Get the given client secret.
String thirdPartySecret = oauthRequest.getClientSecret();
if(thirdPartySecret == null) {
// Create the OAuth response.
OAuthResponse oauthResponse =
OAuthASResponse
.errorResponse(HttpServletResponse.SC_BAD_REQUEST)
.setError(TokenResponse.INVALID_CLIENT)
.setErrorDescription("The client secret is required.")
.buildJSONMessage();
// Set the status and return the error message.
response.setStatus(oauthResponse.getResponseStatus());
return oauthResponse.getBody();
}
// Make sure the client gave the right secret.
else if(! thirdPartySecret.equals(thirdParty.getSecret())) {
// Create the OAuth response.
OAuthResponse oauthResponse =
OAuthASResponse
.errorResponse(HttpServletResponse.SC_BAD_REQUEST)
.setError(TokenResponse.INVALID_CLIENT)
.setErrorDescription("The client secret is incorrect.")
.buildJSONMessage();
// Set the status and return the error message.
response.setStatus(oauthResponse.getResponseStatus());
return oauthResponse.getBody();
}
// Get the grant-type.
GrantType grantType;
String grantTypeString = oauthRequest.getGrantType();
if(GrantType.AUTHORIZATION_CODE.toString().equals(grantTypeString)) {
grantType = GrantType.AUTHORIZATION_CODE;
}
else if(GrantType.CLIENT_CREDENTIALS.toString().equals(grantTypeString)) {
grantType = GrantType.CLIENT_CREDENTIALS;
}
else if(GrantType.PASSWORD.toString().equals(grantTypeString)) {
grantType = GrantType.PASSWORD;
}
else if(GrantType.REFRESH_TOKEN.toString().equals(grantTypeString)) {
grantType = GrantType.REFRESH_TOKEN;
}
else {
// Create the OAuth response.
OAuthResponse oauthResponse =
OAuthASResponse
.errorResponse(HttpServletResponse.SC_BAD_REQUEST)
.setError(TokenResponse.INVALID_GRANT)
.setErrorDescription(
"The grant type is unknown: " + grantTypeString)
.buildJSONMessage();
// Set the status and return the error message.
response.setStatus(oauthResponse.getResponseStatus());
return oauthResponse.getBody();
}
// Handle the different types of token requests.
AuthorizationToken token;
if(GrantType.AUTHORIZATION_CODE.equals(grantType)) {
// Attempt to get the code.
String codeString = oauthRequest.getCode();
if(codeString == null) {
// Create the OAuth response.
OAuthResponse oauthResponse =
OAuthASResponse
.errorResponse(HttpServletResponse.SC_BAD_REQUEST)
.setError(TokenResponse.INVALID_REQUEST)
.setErrorDescription(
"An authorization code must be given to be " +
"exchanged for an authorization token.")
.buildJSONMessage();
// Set the status and return the error message.
response.setStatus(oauthResponse.getResponseStatus());
return oauthResponse.getBody();
}
// Attempt to lookup the actual AuthorizationCode object.
AuthorizationCode code =
AuthorizationCodeBin.getInstance().getCode(codeString);
// If the code doesn't exist, reject the request.
if(code == null) {
// Create the OAuth response.
OAuthResponse oauthResponse =
OAuthASResponse
.errorResponse(HttpServletResponse.SC_BAD_REQUEST)
.setError(TokenResponse.INVALID_REQUEST)
.setErrorDescription(
"The given authorization code is unknown: " +
codeString)
.buildJSONMessage();
// Set the status and return the error message.
response.setStatus(oauthResponse.getResponseStatus());
return oauthResponse.getBody();
}
// Verify that the client asking for a token is the same as the one
// that requested the code.
if(! code.getThirdParty().getId().equals(thirdParty.getId())) {
// Create the OAuth response.
OAuthResponse oauthResponse =
OAuthASResponse
.errorResponse(HttpServletResponse.SC_BAD_REQUEST)
.setError(TokenResponse.INVALID_REQUEST)
.setErrorDescription(
"This client is not allowed to reference this " +
"code: " +
codeString)
.buildJSONMessage();
// Set the status and return the error message.
response.setStatus(oauthResponse.getResponseStatus());
return oauthResponse.getBody();
}
// If the code has expired, reject the request.
if(System.currentTimeMillis() > code.getExpirationTime()) {
// Create the OAuth response.
OAuthResponse oauthResponse =
OAuthASResponse
.errorResponse(HttpServletResponse.SC_BAD_REQUEST)
.setError(TokenResponse.INVALID_REQUEST)
.setErrorDescription(
"The given authorization code has expired: " +
codeString)
.buildJSONMessage();
// Set the status and return the error message.
response.setStatus(oauthResponse.getResponseStatus());
return oauthResponse.getBody();
}
// Use the code to lookup the response information and error out if
// a user has not yet verified it.
AuthorizationCodeResponse codeResponse =
AuthorizationCodeResponseBin
.getInstance().getResponse(code.getCode());
if(codeResponse == null) {
// Create the OAuth response.
OAuthResponse oauthResponse =
OAuthASResponse
.errorResponse(HttpServletResponse.SC_BAD_REQUEST)
.setError(TokenResponse.INVALID_REQUEST)
.setErrorDescription(
"A user has not yet verified the code: " +
codeString)
.buildJSONMessage();
// Set the status and return the error message.
response.setStatus(oauthResponse.getResponseStatus());
return oauthResponse.getBody();
}
// Determine if the user granted access and, if not, error out.
if(! codeResponse.getGranted()) {
// Create the OAuth response.
OAuthResponse oauthResponse =
OAuthASResponse
.errorResponse(HttpServletResponse.SC_BAD_REQUEST)
.setError(TokenResponse.INVALID_REQUEST)
.setErrorDescription(
"The user denied the authorization: " + codeString)
.buildJSONMessage();
// Set the status and return the error message.
response.setStatus(oauthResponse.getResponseStatus());
return oauthResponse.getBody();
}
// Create a new token.
token = new AuthorizationToken(codeResponse);
}
// Handle a third-party refreshing an existing token.
else if(GrantType.REFRESH_TOKEN.equals(grantType)) {
// Get the refresh token from the request.
String refreshToken = oauthRequest.getRefreshToken();
if(refreshToken == null) {
// Create the OAuth response.
OAuthResponse oauthResponse =
OAuthASResponse
.errorResponse(HttpServletResponse.SC_BAD_REQUEST)
.setError(TokenResponse.INVALID_REQUEST)
.setErrorDescription(
"An refresh token must be given to be exchanged " +
"for a new authorization token.")
.buildJSONMessage();
// Set the status and return the error message.
response.setStatus(oauthResponse.getResponseStatus());
return oauthResponse.getBody();
}
// Use the refresh token to lookup the actual refresh token.
AuthorizationToken currentToken =
AuthorizationTokenBin
.getInstance().getTokenFromRefreshToken(refreshToken);
if(currentToken == null) {
// Create the OAuth response.
OAuthResponse oauthResponse =
OAuthASResponse
.errorResponse(HttpServletResponse.SC_BAD_REQUEST)
.setError(TokenResponse.INVALID_REQUEST)
.setErrorDescription("The refresh token is unknown.")
.buildJSONMessage();
// Set the status and return the error message.
response.setStatus(oauthResponse.getResponseStatus());
return oauthResponse.getBody();
}
// Verify that the client asking for a token is the same as the one
// that was issued the refresh token.
// This is probably a very serious offense and should probably
// raise some serious red flags!
if(!
currentToken
.getThirdParty().getId().equals(thirdParty.getId())) {
// Create the OAuth response.
OAuthResponse oauthResponse =
OAuthASResponse
.errorResponse(HttpServletResponse.SC_BAD_REQUEST)
.setError(TokenResponse.INVALID_REQUEST)
.setErrorDescription(
"This token does not belong to this client.")
.buildJSONMessage();
// Set the status and return the error message.
response.setStatus(oauthResponse.getResponseStatus());
return oauthResponse.getBody();
}
// Create a new authorization token from the current one.
token = new AuthorizationToken(currentToken);
}
// If the grant-type is unknown, then we do not yet understand how
// the request is built and, therefore, can do nothing more than
// reject it via an OmhException.
else {
// Create the OAuth response.
OAuthResponse oauthResponse =
OAuthASResponse
.errorResponse(HttpServletResponse.SC_BAD_REQUEST)
.setError(TokenResponse.UNSUPPORTED_GRANT_TYPE)
.setErrorDescription(
"The grant type must be one of '" +
GrantType.AUTHORIZATION_CODE.toString() +
"' or '" +
GrantType.REFRESH_TOKEN.toString() +
"': " +
grantType.toString())
.buildJSONMessage();
// Set the status and return the error message.
response.setStatus(oauthResponse.getResponseStatus());
return oauthResponse.getBody();
}
// Store the new token.
AuthorizationTokenBin.getInstance().storeToken(token);
// Build the response.
OAuthResponse oauthResponse =
OAuthASResponse
.tokenResponse(HttpServletResponse.SC_OK)
.setAccessToken(token.getAccessToken())
.setExpiresIn(Long.valueOf(token.getExpirationIn() / 1000).toString())
.setRefreshToken(token.getRefreshToken())
.setTokenType(TokenType.BEARER.toString())
.buildJSONMessage();
// Set the status.
response.setStatus(oauthResponse.getResponseStatus());
// Set the content-type.
response.setContentType("application/json");
// Add the headers.
Map<String, String> headers = oauthResponse.getHeaders();
for(String headerKey : headers.keySet()) {
response.addHeader(headerKey, headers.get(headerKey));
}
// Return the body.
return oauthResponse.getBody();
}