checkpoint on oauth for static site

- store state + redirectUri in a table
- redirect again to get code & state out of query string
- add meta-data validation to oauth2 module
This commit is contained in:
2025-03-24 09:25:53 -05:00
parent f99c39e0f6
commit 410175a133
9 changed files with 369 additions and 58 deletions

View File

@ -137,6 +137,7 @@ import com.kingsrook.qqq.middleware.javalin.misc.DownloadFileSupplementalAction;
import io.javalin.Javalin;
import io.javalin.apibuilder.EndpointGroup;
import io.javalin.http.Context;
import io.javalin.http.Cookie;
import io.javalin.http.UploadedFile;
import org.apache.commons.io.FileUtils;
import org.eclipse.jetty.http.HttpStatus;
@ -535,14 +536,24 @@ public class QJavalinImplementation
try
{
///////////////////////////////////////////////
// note: duplicated in ExecutorSessionUtils //
///////////////////////////////////////////////
Map<String, String> authenticationContext = new HashMap<>();
String sessionIdCookieValue = context.cookie(SESSION_ID_COOKIE_NAME);
String sessionUuidCookieValue = context.cookie(Auth0AuthenticationModule.SESSION_UUID_KEY);
String authorizationHeaderValue = context.header("Authorization");
String apiKeyHeaderValue = context.header("x-api-key");
String codeQueryParamValue = context.queryParam("code");
String stateQueryParamValue = context.queryParam("state");
if(StringUtils.hasContent(sessionIdCookieValue))
if(StringUtils.hasContent(codeQueryParamValue) && StringUtils.hasContent(stateQueryParamValue))
{
authenticationContext.put("code", codeQueryParamValue);
authenticationContext.put("state", stateQueryParamValue);
}
else if(StringUtils.hasContent(sessionIdCookieValue))
{
///////////////////////////////////////////////////////
// sessionId - maybe used by table-based auth module //

View File

@ -60,14 +60,24 @@ public class ExecutorSessionUtils
try
{
/////////////////////////////////////////////////
// note: duplicated in QJavalinImplementation //
/////////////////////////////////////////////////
Map<String, String> authenticationContext = new HashMap<>();
String sessionIdCookieValue = context.cookie(SESSION_ID_COOKIE_NAME);
String sessionUuidCookieValue = context.cookie(Auth0AuthenticationModule.SESSION_UUID_KEY);
String authorizationHeaderValue = context.header("Authorization");
String apiKeyHeaderValue = context.header("x-api-key");
String codeQueryParamValue = context.queryParam("code");
String stateQueryParamValue = context.queryParam("state");
if(StringUtils.hasContent(sessionIdCookieValue))
if(StringUtils.hasContent(codeQueryParamValue) && StringUtils.hasContent(stateQueryParamValue))
{
authenticationContext.put("code", codeQueryParamValue);
authenticationContext.put("state", stateQueryParamValue);
}
else if(StringUtils.hasContent(sessionIdCookieValue))
{
///////////////////////////////////////////////////////
// sessionId - maybe used by table-based auth module //

View File

@ -55,6 +55,23 @@ public class SimpleRouteAuthenticator implements RouteAuthenticatorInterface
{
QSession qSession = QJavalinImplementation.setupSession(context, null);
LOG.debug("Session has been activated", logPair("uuid", qSession.getUuid()));
if(context.queryParamMap().containsKey("code") && context.queryParamMap().containsKey("state"))
{
//////////////////////////////////////////////////////////////////////////
// if this request was a callback from oauth, with code & state params, //
// then redirect one last time removing those from the query string //
//////////////////////////////////////////////////////////////////////////
String redirectURL = context.fullUrl().replace("code=" + context.queryParam("code"), "")
.replace("state=" + context.queryParam("state"), "")
.replaceFirst("&+$", "")
.replaceFirst("\\?&", "?")
.replaceFirst("\\?$", "");
context.redirect(redirectURL);
LOG.debug("Redirecting request to remove code and state parameters");
return (false);
}
return (true);
}
catch(QAuthenticationException e)