Added some more logging to OAuth2 and a token listener

This commit is contained in:
Ziver Koc 2020-11-27 01:59:35 +01:00
parent 2786e93df2
commit 8bbb651169
3 changed files with 51 additions and 29 deletions

View file

@ -100,34 +100,34 @@ public class OAuth2AuthorizationPage implements HttpPage {
// Validate parameters
// -----------------------------------------------
HttpURL url = null;
String clientId = request.get("client_id");
// Validate 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;
}
HttpURL url = null;
try {
url = new HttpURL(URLDecoder.decode(request.get("redirect_uri")));
} catch(Exception e) {}
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;
}
// Validate 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;
}
String clientId = request.get("client_id");
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.");
return;
}
@ -135,7 +135,7 @@ public class OAuth2AuthorizationPage implements HttpPage {
// Validate 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.");
return;
}
@ -156,13 +156,14 @@ public class OAuth2AuthorizationPage implements HttpPage {
case RESPONSE_TYPE_PASSWORD:
case RESPONSE_TYPE_CREDENTIALS:
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"));
return;
}
// Setup the redirect
logger.warning("OAuth2 successful authorization of client: " + clientId);
redirect(out, url);
}
@ -170,7 +171,9 @@ public class OAuth2AuthorizationPage implements HttpPage {
// 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.println(description);
}
@ -184,8 +187,8 @@ public class OAuth2AuthorizationPage implements HttpPage {
* @param state
* @param description
*/
private static void errorRedirect(HttpPrintStream out, HttpURL url, String error, String state, String description) {
logger.warning("OAuth2 Authorization Error(" + error + "): " + description);
private static void errorRedirect(HttpPrintStream out, String clientId, HttpURL url, String error, String state, String description) {
logger.warning("OAuth2 Client" + (clientId!=null ? "(" + clientId + ")" : "") + " Authorization Error: " + error + " = " + description);
out.setHeader(HttpHeader.HEADER_CONTENT_TYPE, "application/x-www-form-urlencoded");
url.setParameter("error", error);

View file

@ -44,6 +44,7 @@ public class OAuth2Registry implements Serializable {
private boolean requireWhitelist = true;
transient private Random random = new Random();
transient private TokenRegistrationListener tokenListener;
// ------------------------------------------------------
@ -161,6 +162,9 @@ public class OAuth2Registry implements Serializable {
if (reg != null) {
reg.accessTokens.put(token, new Timer(timeoutMillis).start());
if (tokenListener != null)
tokenListener.onTokenRegistration(clientId, token, timeoutMillis);
return timeoutMillis;
}
return -1;
@ -204,6 +208,25 @@ public class OAuth2Registry implements Serializable {
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) {

View file

@ -102,15 +102,14 @@ public class OAuth2TokenPage extends HttpJsonPage {
// -----------------------------------------------
DataNode jsonRes = new DataNode(DataNode.DataType.Map);
// Validate grant_type
String grantType = request.get("grant_type");
String codeKey;
String clientId = null;
// Validate grant_type
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) {
case "authorization_code":
@ -121,15 +120,15 @@ public class OAuth2TokenPage extends HttpJsonPage {
clientId = request.get("client_id");
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))
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
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
// "redirect_uri" parameter was included in the initial authorization
@ -143,7 +142,7 @@ public class OAuth2TokenPage extends HttpJsonPage {
break;
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
@ -151,10 +150,10 @@ public class OAuth2TokenPage extends HttpJsonPage {
String authorizationCode = request.get(codeKey);
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))
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
@ -163,6 +162,8 @@ public class OAuth2TokenPage extends HttpJsonPage {
if (clientId == null)
clientId = registry.getClientIdForAuthenticationCode(authorizationCode);
logger.warning("OAuth2 successful token provisioning for client: " + clientId);
String token = registry.generateToken();
long timeoutMillis = registry.registerAccessToken(clientId, token);
@ -182,7 +183,6 @@ public class OAuth2TokenPage extends HttpJsonPage {
}
// ------------------------------------------------------
// 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>
*
* @param out
* @param error
* @param state
* @param description
* @return A DataNode containing the error response
*/
private static DataNode errorResponse(HttpPrintStream out, String error, String state, String description) {
logger.warning("OAuth2 Token Error(" + error + ") for client: " + description);
private static DataNode errorResponse(HttpPrintStream out, String clientId, String error, String state, String description) {
logger.warning("OAuth2 Client" + (clientId!=null ? "(" + clientId + ")" : "") + " Token Error: " + error + " = " + description);
out.setResponseStatusCode(400);