Added some more logging to OAuth2 and a token listener
This commit is contained in:
parent
2786e93df2
commit
8bbb651169
3 changed files with 51 additions and 29 deletions
|
|
@ -100,34 +100,34 @@ public class OAuth2AuthorizationPage implements HttpPage {
|
||||||
// Validate parameters
|
// Validate parameters
|
||||||
// -----------------------------------------------
|
// -----------------------------------------------
|
||||||
|
|
||||||
|
HttpURL url = null;
|
||||||
|
String clientId = request.get("client_id");
|
||||||
|
|
||||||
// Validate redirect_uri
|
// Validate redirect_uri
|
||||||
|
|
||||||
if (!request.containsKey("redirect_uri")) {
|
if (!request.containsKey("redirect_uri")) {
|
||||||
errorResponse(out, "Bad Request, missing parameter: redirect_uri");
|
errorResponse(out, clientId, "Bad Request, missing parameter: redirect_uri");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpURL url = null;
|
|
||||||
try {
|
try {
|
||||||
url = new HttpURL(URLDecoder.decode(request.get("redirect_uri")));
|
url = new HttpURL(URLDecoder.decode(request.get("redirect_uri")));
|
||||||
} catch(Exception e) {}
|
} catch(Exception e) {}
|
||||||
|
|
||||||
if (url == null || !"HTTPS".equalsIgnoreCase(url.getProtocol())) {
|
if (url == null || !"HTTPS".equalsIgnoreCase(url.getProtocol())) {
|
||||||
errorResponse(out, "Invalid redirect URL: " + request.get("redirect_uri"));
|
errorResponse(out, clientId, "Invalid redirect URL: " + request.get("redirect_uri"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate client_id
|
// Validate client_id
|
||||||
|
|
||||||
if (!request.containsKey("client_id")) {
|
if (!request.containsKey("client_id")) {
|
||||||
errorResponse(out, "Bad Request, missing parameter: client_id");
|
errorResponse(out, clientId, "Bad Request, missing parameter: client_id");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String clientId = request.get("client_id");
|
|
||||||
|
|
||||||
if (!registry.isClientIdValid(clientId)) {
|
if (!registry.isClientIdValid(clientId)) {
|
||||||
errorRedirect(out, url, ERROR_UNAUTHORIZED_CLIENT, request.get("state"),
|
errorRedirect(out, clientId, url, ERROR_UNAUTHORIZED_CLIENT, request.get("state"),
|
||||||
"Bad Request, invalid client_id value.");
|
"Bad Request, invalid client_id value.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -135,7 +135,7 @@ public class OAuth2AuthorizationPage implements HttpPage {
|
||||||
// Validate response_type
|
// Validate response_type
|
||||||
|
|
||||||
if (!request.containsKey("response_type")) {
|
if (!request.containsKey("response_type")) {
|
||||||
errorRedirect(out, url, ERROR_INVALID_REQUEST, request.get("state"),
|
errorRedirect(out, clientId, url, ERROR_INVALID_REQUEST, request.get("state"),
|
||||||
"Missing parameter response_type.");
|
"Missing parameter response_type.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -156,13 +156,14 @@ public class OAuth2AuthorizationPage implements HttpPage {
|
||||||
case RESPONSE_TYPE_PASSWORD:
|
case RESPONSE_TYPE_PASSWORD:
|
||||||
case RESPONSE_TYPE_CREDENTIALS:
|
case RESPONSE_TYPE_CREDENTIALS:
|
||||||
default:
|
default:
|
||||||
errorRedirect(out, url, ERROR_INVALID_REQUEST, request.get("state"),
|
errorRedirect(out, clientId, url, ERROR_INVALID_REQUEST, request.get("state"),
|
||||||
"unsupported response_type: " + request.get("response_type"));
|
"unsupported response_type: " + request.get("response_type"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup the redirect
|
// Setup the redirect
|
||||||
|
|
||||||
|
logger.warning("OAuth2 successful authorization of client: " + clientId);
|
||||||
redirect(out, url);
|
redirect(out, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -170,7 +171,9 @@ public class OAuth2AuthorizationPage implements HttpPage {
|
||||||
// Error handling
|
// Error handling
|
||||||
// ------------------------------------------------------
|
// ------------------------------------------------------
|
||||||
|
|
||||||
private static void errorResponse(HttpPrintStream out, String description) {
|
private static void errorResponse(HttpPrintStream out, String clientId, String description) {
|
||||||
|
logger.warning("OAuth2 Client" + (clientId!=null ? "(" + clientId + ")" : "") + " Authorization Error: " + description);
|
||||||
|
|
||||||
out.setResponseStatusCode(400);
|
out.setResponseStatusCode(400);
|
||||||
out.println(description);
|
out.println(description);
|
||||||
}
|
}
|
||||||
|
|
@ -184,8 +187,8 @@ public class OAuth2AuthorizationPage implements HttpPage {
|
||||||
* @param state
|
* @param state
|
||||||
* @param description
|
* @param description
|
||||||
*/
|
*/
|
||||||
private static void errorRedirect(HttpPrintStream out, HttpURL url, String error, String state, String description) {
|
private static void errorRedirect(HttpPrintStream out, String clientId, HttpURL url, String error, String state, String description) {
|
||||||
logger.warning("OAuth2 Authorization Error(" + error + "): " + description);
|
logger.warning("OAuth2 Client" + (clientId!=null ? "(" + clientId + ")" : "") + " Authorization Error: " + error + " = " + description);
|
||||||
|
|
||||||
out.setHeader(HttpHeader.HEADER_CONTENT_TYPE, "application/x-www-form-urlencoded");
|
out.setHeader(HttpHeader.HEADER_CONTENT_TYPE, "application/x-www-form-urlencoded");
|
||||||
url.setParameter("error", error);
|
url.setParameter("error", error);
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ public class OAuth2Registry implements Serializable {
|
||||||
private boolean requireWhitelist = true;
|
private boolean requireWhitelist = true;
|
||||||
|
|
||||||
transient private Random random = new Random();
|
transient private Random random = new Random();
|
||||||
|
transient private TokenRegistrationListener tokenListener;
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------
|
// ------------------------------------------------------
|
||||||
|
|
@ -161,6 +162,9 @@ public class OAuth2Registry implements Serializable {
|
||||||
|
|
||||||
if (reg != null) {
|
if (reg != null) {
|
||||||
reg.accessTokens.put(token, new Timer(timeoutMillis).start());
|
reg.accessTokens.put(token, new Timer(timeoutMillis).start());
|
||||||
|
|
||||||
|
if (tokenListener != null)
|
||||||
|
tokenListener.onTokenRegistration(clientId, token, timeoutMillis);
|
||||||
return timeoutMillis;
|
return timeoutMillis;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -204,6 +208,25 @@ public class OAuth2Registry implements Serializable {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------
|
||||||
|
// Listeners
|
||||||
|
// ------------------------------------------------------
|
||||||
|
|
||||||
|
public void setTokenListener(TokenRegistrationListener listener) {
|
||||||
|
this.tokenListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface TokenRegistrationListener {
|
||||||
|
/**
|
||||||
|
* Method will be called when a new token is successfully registered on a client
|
||||||
|
*
|
||||||
|
* @param clientId the client ID that got the specified token
|
||||||
|
* @param token a String token that has ben generated and provided to the client
|
||||||
|
* @param timeoutMillis the expiration time of the token
|
||||||
|
*/
|
||||||
|
void onTokenRegistration(String clientId, String token, long timeoutMillis);
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------
|
// ------------------------------------------------------
|
||||||
|
|
||||||
private ClientRegister getClientRegister(String clientId) {
|
private ClientRegister getClientRegister(String clientId) {
|
||||||
|
|
|
||||||
|
|
@ -102,15 +102,14 @@ public class OAuth2TokenPage extends HttpJsonPage {
|
||||||
// -----------------------------------------------
|
// -----------------------------------------------
|
||||||
|
|
||||||
DataNode jsonRes = new DataNode(DataNode.DataType.Map);
|
DataNode jsonRes = new DataNode(DataNode.DataType.Map);
|
||||||
|
|
||||||
// Validate grant_type
|
|
||||||
|
|
||||||
String grantType = request.get("grant_type");
|
String grantType = request.get("grant_type");
|
||||||
String codeKey;
|
String codeKey;
|
||||||
String clientId = null;
|
String clientId = null;
|
||||||
|
|
||||||
|
// Validate grant_type
|
||||||
|
|
||||||
if (grantType == null)
|
if (grantType == null)
|
||||||
return errorResponse(out, ERROR_INVALID_REQUEST , request.get("state"), "Missing mandatory parameter grant_type.");
|
return errorResponse(out, clientId, ERROR_INVALID_REQUEST , request.get("state"), "Missing mandatory parameter grant_type.");
|
||||||
|
|
||||||
switch (grantType) {
|
switch (grantType) {
|
||||||
case "authorization_code":
|
case "authorization_code":
|
||||||
|
|
@ -121,15 +120,15 @@ public class OAuth2TokenPage extends HttpJsonPage {
|
||||||
clientId = request.get("client_id");
|
clientId = request.get("client_id");
|
||||||
|
|
||||||
if (clientId == null)
|
if (clientId == null)
|
||||||
return errorResponse(out, ERROR_INVALID_REQUEST , request.get("state"), "Missing mandatory parameter: client_id");
|
return errorResponse(out, clientId, ERROR_INVALID_REQUEST , request.get("state"), "Missing mandatory parameter: client_id");
|
||||||
|
|
||||||
if (!registry.isClientIdValid(clientId))
|
if (!registry.isClientIdValid(clientId))
|
||||||
return errorResponse(out, ERROR_INVALID_CLIENT , request.get("state"), "Invalid client_id value.");
|
return errorResponse(out, clientId, ERROR_INVALID_CLIENT , request.get("state"), "Invalid client_id value.");
|
||||||
|
|
||||||
// Validate redirect_uri
|
// Validate redirect_uri
|
||||||
|
|
||||||
if (!request.containsKey("redirect_uri"))
|
if (!request.containsKey("redirect_uri"))
|
||||||
return errorResponse(out, ERROR_INVALID_REQUEST , request.get("state"), "Missing mandatory parameter: redirect_uri");
|
return errorResponse(out, clientId, ERROR_INVALID_REQUEST , request.get("state"), "Missing mandatory parameter: redirect_uri");
|
||||||
|
|
||||||
// TODO: ensure that the "redirect_uri" parameter is present if the
|
// TODO: ensure that the "redirect_uri" parameter is present if the
|
||||||
// "redirect_uri" parameter was included in the initial authorization
|
// "redirect_uri" parameter was included in the initial authorization
|
||||||
|
|
@ -143,7 +142,7 @@ public class OAuth2TokenPage extends HttpJsonPage {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return errorResponse(out, ERROR_UNSUPPORTED_GRANT_TYPE, request.get("state"), "Unsupported grant_type: " + request.containsKey("grant_type"));
|
return errorResponse(out, clientId, ERROR_UNSUPPORTED_GRANT_TYPE, request.get("state"), "Unsupported grant_type: " + request.containsKey("grant_type"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate code and refresh_token
|
// Validate code and refresh_token
|
||||||
|
|
@ -151,10 +150,10 @@ public class OAuth2TokenPage extends HttpJsonPage {
|
||||||
String authorizationCode = request.get(codeKey);
|
String authorizationCode = request.get(codeKey);
|
||||||
|
|
||||||
if (authorizationCode == null)
|
if (authorizationCode == null)
|
||||||
return errorResponse(out, ERROR_INVALID_REQUEST , request.get("state"), "Missing mandatory parameter: " + codeKey);
|
return errorResponse(out, clientId, ERROR_INVALID_REQUEST , request.get("state"), "Missing mandatory parameter: " + codeKey);
|
||||||
|
|
||||||
if (!registry.isAuthorizationCodeValid(authorizationCode))
|
if (!registry.isAuthorizationCodeValid(authorizationCode))
|
||||||
return errorResponse(out, ERROR_INVALID_GRANT, request.get("state"), "Invalid " + codeKey + " value.");
|
return errorResponse(out, clientId, ERROR_INVALID_GRANT, request.get("state"), "Invalid " + codeKey + " value.");
|
||||||
|
|
||||||
// -----------------------------------------------
|
// -----------------------------------------------
|
||||||
// Handle request
|
// Handle request
|
||||||
|
|
@ -163,6 +162,8 @@ public class OAuth2TokenPage extends HttpJsonPage {
|
||||||
if (clientId == null)
|
if (clientId == null)
|
||||||
clientId = registry.getClientIdForAuthenticationCode(authorizationCode);
|
clientId = registry.getClientIdForAuthenticationCode(authorizationCode);
|
||||||
|
|
||||||
|
logger.warning("OAuth2 successful token provisioning for client: " + clientId);
|
||||||
|
|
||||||
String token = registry.generateToken();
|
String token = registry.generateToken();
|
||||||
long timeoutMillis = registry.registerAccessToken(clientId, token);
|
long timeoutMillis = registry.registerAccessToken(clientId, token);
|
||||||
|
|
||||||
|
|
@ -182,7 +183,6 @@ public class OAuth2TokenPage extends HttpJsonPage {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------
|
// ------------------------------------------------------
|
||||||
// Error handling
|
// Error handling
|
||||||
// ------------------------------------------------------
|
// ------------------------------------------------------
|
||||||
|
|
@ -190,14 +190,10 @@ public class OAuth2TokenPage extends HttpJsonPage {
|
||||||
/**
|
/**
|
||||||
* @see <a href="https://tools.ietf.org/html/rfc6749#section-5.2">RFC 6749: Chapter 5.2</a>
|
* @see <a href="https://tools.ietf.org/html/rfc6749#section-5.2">RFC 6749: Chapter 5.2</a>
|
||||||
*
|
*
|
||||||
* @param out
|
|
||||||
* @param error
|
|
||||||
* @param state
|
|
||||||
* @param description
|
|
||||||
* @return A DataNode containing the error response
|
* @return A DataNode containing the error response
|
||||||
*/
|
*/
|
||||||
private static DataNode errorResponse(HttpPrintStream out, String error, String state, String description) {
|
private static DataNode errorResponse(HttpPrintStream out, String clientId, String error, String state, String description) {
|
||||||
logger.warning("OAuth2 Token Error(" + error + ") for client: " + description);
|
logger.warning("OAuth2 Client" + (clientId!=null ? "(" + clientId + ")" : "") + " Token Error: " + error + " = " + description);
|
||||||
|
|
||||||
out.setResponseStatusCode(400);
|
out.setResponseStatusCode(400);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue