mirror of
https://github.com/Kingsrook/qqq.git
synced 2025-07-18 13:10:44 +00:00
CE-937 Add concept of customizers to authentication modules; basic implementation within auth0 for customizing session/security keys
This commit is contained in:
@ -153,6 +153,7 @@ public class QInstanceValidator
|
||||
try
|
||||
{
|
||||
validateBackends(qInstance);
|
||||
validateAuthentication(qInstance);
|
||||
validateAutomationProviders(qInstance);
|
||||
validateTables(qInstance, joinGraph);
|
||||
validateProcesses(qInstance);
|
||||
@ -383,6 +384,23 @@ public class QInstanceValidator
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private void validateAuthentication(QInstance qInstance)
|
||||
{
|
||||
QAuthenticationMetaData authentication = qInstance.getAuthentication();
|
||||
if(authentication != null)
|
||||
{
|
||||
if(authentication.getCustomizer() != null)
|
||||
{
|
||||
validateSimpleCodeReference("Instance Authentication meta data customizer ", authentication.getCustomizer(), QAuthenticationModuleCustomizerInterface.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
|
@ -28,6 +28,7 @@ import com.fasterxml.jackson.annotation.JsonFilter;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QAuthenticationType;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.TopLevelMetaDataInterface;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
@ -43,6 +44,7 @@ public class QAuthenticationMetaData implements TopLevelMetaDataInterface
|
||||
@JsonFilter("secretsFilter")
|
||||
private Map<String, String> values;
|
||||
|
||||
private QCodeReference customizer;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
@ -192,4 +194,35 @@ public class QAuthenticationMetaData implements TopLevelMetaDataInterface
|
||||
qInstance.setAuthentication(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Getter for customizer
|
||||
*******************************************************************************/
|
||||
public QCodeReference getCustomizer()
|
||||
{
|
||||
return (this.customizer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Setter for customizer
|
||||
*******************************************************************************/
|
||||
public void setCustomizer(QCodeReference customizer)
|
||||
{
|
||||
this.customizer = customizer;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Fluent setter for customizer
|
||||
*******************************************************************************/
|
||||
public QAuthenticationMetaData withCustomizer(QCodeReference customizer)
|
||||
{
|
||||
this.customizer = customizer;
|
||||
return (this);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* QQQ - Low-code Application Framework for Engineers.
|
||||
* Copyright (C) 2021-2024. Kingsrook, LLC
|
||||
* 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States
|
||||
* contact@kingsrook.com
|
||||
* https://github.com/Kingsrook/
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.kingsrook.qqq.backend.core.modules.authentication;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||
import com.kingsrook.qqq.backend.core.model.session.QSession;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Interface for customizing behavior of an Authentication module.
|
||||
*******************************************************************************/
|
||||
public interface QAuthenticationModuleCustomizerInterface
|
||||
{
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
default void addSecurityKeyValueToSession(QSession session, String keyName, Serializable value)
|
||||
{
|
||||
session.withSecurityKeyValue(keyName, value);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
default void customizeSession(QInstance qInstance, QSession qSession, Map<String, Object> context)
|
||||
{
|
||||
//////////
|
||||
// noop //
|
||||
//////////
|
||||
}
|
||||
|
||||
}
|
@ -47,6 +47,7 @@ import com.auth0.jwt.exceptions.JWTVerificationException;
|
||||
import com.auth0.jwt.exceptions.TokenExpiredException;
|
||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||
import com.auth0.net.Response;
|
||||
import com.kingsrook.qqq.backend.core.actions.customizers.QCodeLoader;
|
||||
import com.kingsrook.qqq.backend.core.actions.tables.GetAction;
|
||||
import com.kingsrook.qqq.backend.core.actions.tables.InsertAction;
|
||||
import com.kingsrook.qqq.backend.core.actions.tables.QueryAction;
|
||||
@ -71,6 +72,7 @@ import com.kingsrook.qqq.backend.core.model.metadata.authentication.Auth0Authent
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.security.QSecurityKeyType;
|
||||
import com.kingsrook.qqq.backend.core.model.session.QSession;
|
||||
import com.kingsrook.qqq.backend.core.model.session.QUser;
|
||||
import com.kingsrook.qqq.backend.core.modules.authentication.QAuthenticationModuleCustomizerInterface;
|
||||
import com.kingsrook.qqq.backend.core.modules.authentication.QAuthenticationModuleInterface;
|
||||
import com.kingsrook.qqq.backend.core.modules.authentication.implementations.model.UserSession;
|
||||
import com.kingsrook.qqq.backend.core.state.InMemoryStateProvider;
|
||||
@ -80,6 +82,7 @@ import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||
import com.kingsrook.qqq.backend.core.utils.JsonUtils;
|
||||
import com.kingsrook.qqq.backend.core.utils.StringUtils;
|
||||
import com.kingsrook.qqq.backend.core.utils.ValueUtils;
|
||||
import com.kingsrook.qqq.backend.core.utils.memoization.Memoization;
|
||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
@ -129,6 +132,19 @@ public class Auth0AuthenticationModule implements QAuthenticationModuleInterface
|
||||
static final String EXPIRED_TOKEN_ERROR = "Token has expired";
|
||||
static final String INVALID_TOKEN_ERROR = "An invalid token was provided";
|
||||
|
||||
private Auth0AuthenticationMetaData metaData;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// do not use this var directly - rather - always call the getCustomizer method //
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
private QAuthenticationModuleCustomizerInterface _customizer = null;
|
||||
private boolean customizerHasBeenRequested = false;
|
||||
|
||||
private static boolean mayMemoize = true;
|
||||
|
||||
private static final Memoization<String, String> getAccessTokenFromSessionUUIDMemoization = new Memoization<String, String>()
|
||||
.withTimeout(Duration.of(1, ChronoUnit.MINUTES))
|
||||
.withMaxSize(1000);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// this is how we allow the actions within this class to work without themselves having a logged-in user. //
|
||||
@ -165,9 +181,12 @@ public class Auth0AuthenticationModule implements QAuthenticationModuleInterface
|
||||
@Override
|
||||
public QSession createSession(QInstance qInstance, Map<String, String> context) throws QAuthenticationException
|
||||
{
|
||||
QInstance contextInstanceBefore = QContext.getQInstance();
|
||||
|
||||
try
|
||||
{
|
||||
Auth0AuthenticationMetaData metaData = (Auth0AuthenticationMetaData) qInstance.getAuthentication();
|
||||
QContext.setQInstance(qInstance);
|
||||
this.metaData = (Auth0AuthenticationMetaData) qInstance.getAuthentication();
|
||||
|
||||
String accessToken = null;
|
||||
if(CollectionUtils.containsKeyWithNonNullValue(context, SESSION_UUID_KEY))
|
||||
@ -252,16 +271,6 @@ public class Auth0AuthenticationModule implements QAuthenticationModuleInterface
|
||||
}
|
||||
}
|
||||
|
||||
/* todo confirm this is deprecated
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// check to see if the session id is a UUID, if so, that means we need to look up the 'actual' token in the access_token table //
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
if(accessToken != null && StringUtils.isUUID(accessToken))
|
||||
{
|
||||
accessToken = lookupActualAccessToken(metaData, accessToken);
|
||||
}
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////
|
||||
// if token wasn't found by now, give up //
|
||||
///////////////////////////////////////////
|
||||
@ -311,6 +320,10 @@ public class Auth0AuthenticationModule implements QAuthenticationModuleInterface
|
||||
LOG.error(message, e);
|
||||
throw (new QAuthenticationException(message));
|
||||
}
|
||||
finally
|
||||
{
|
||||
QContext.setQInstance(contextInstanceBefore);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -346,6 +359,11 @@ public class Auth0AuthenticationModule implements QAuthenticationModuleInterface
|
||||
*******************************************************************************/
|
||||
private QSession buildAndValidateSession(QInstance qInstance, String accessToken) throws JwkException
|
||||
{
|
||||
QSession beforeSession = QContext.getQSession();
|
||||
|
||||
try
|
||||
{
|
||||
QContext.setQSession(getChickenAndEggSession());
|
||||
QSession qSession = buildQSessionFromToken(accessToken, qInstance);
|
||||
if(isSessionValid(qInstance, qSession))
|
||||
{
|
||||
@ -367,6 +385,11 @@ public class Auth0AuthenticationModule implements QAuthenticationModuleInterface
|
||||
|
||||
return (qSession);
|
||||
}
|
||||
finally
|
||||
{
|
||||
QContext.setQSession(beforeSession);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -509,7 +532,7 @@ public class Auth0AuthenticationModule implements QAuthenticationModuleInterface
|
||||
*******************************************************************************/
|
||||
private void validateToken(QInstance qInstance, String tokenString) throws JwkException
|
||||
{
|
||||
Auth0AuthenticationMetaData metaData = (Auth0AuthenticationMetaData) qInstance.getAuthentication();
|
||||
this.metaData = (Auth0AuthenticationMetaData) qInstance.getAuthentication();
|
||||
|
||||
DecodedJWT idToken = JWT.decode(tokenString);
|
||||
JwkProvider provider = new UrlJwkProvider(metaData.getBaseUrl());
|
||||
@ -567,10 +590,10 @@ public class Auth0AuthenticationModule implements QAuthenticationModuleInterface
|
||||
qSession.setIdReference(accessToken);
|
||||
qSession.setUser(qUser);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// put the user id reference in security key value for usierId key //
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
qSession.withSecurityKeyValue("userId", qUser.getIdReference());
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// put the user id reference in security key value for userId key //
|
||||
////////////////////////////////////////////////////////////////////
|
||||
addSecurityKeyValueToSession(qSession, "userId", qUser.getIdReference());
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// set permissions in the session from the JWT //
|
||||
@ -582,11 +605,42 @@ public class Auth0AuthenticationModule implements QAuthenticationModuleInterface
|
||||
///////////////////////////////////////////////////
|
||||
setSecurityKeysInSessionFromJwtPayload(qInstance, payload, qSession);
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// allow customizer to do custom things here, if so desired //
|
||||
//////////////////////////////////////////////////////////////
|
||||
if(getCustomizer() != null)
|
||||
{
|
||||
getCustomizer().customizeSession(qInstance, qSession, Map.of("jwtPayloadJsonObject", payload));
|
||||
}
|
||||
|
||||
return (qSession);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private void addSecurityKeyValueToSession(QSession qSession, String key, String value)
|
||||
{
|
||||
if(getCustomizer() == null)
|
||||
{
|
||||
///////////////////////////////////////////////////
|
||||
// if there's no customizer, do the direct thing //
|
||||
///////////////////////////////////////////////////
|
||||
qSession.withSecurityKeyValue(key, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
///////////////////////////////////////////////////////////
|
||||
// else have the customizer add the value to the session //
|
||||
///////////////////////////////////////////////////////////
|
||||
getCustomizer().addSecurityKeyValueToSession(qSession, key, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@ -616,7 +670,7 @@ public class Auth0AuthenticationModule implements QAuthenticationModuleInterface
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void setSecurityKeysInSessionFromJwtPayload(QInstance qInstance, JSONObject payload, QSession qSession)
|
||||
void setSecurityKeysInSessionFromJwtPayload(QInstance qInstance, JSONObject payload, QSession qSession)
|
||||
{
|
||||
for(String payloadKey : List.of("com.kingsrook.qqq.app_metadata", "com.kingsrook.qqq.client_metadata"))
|
||||
{
|
||||
@ -668,7 +722,7 @@ public class Auth0AuthenticationModule implements QAuthenticationModuleInterface
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private static void setSecurityKeyValuesFromToken(Set<String> allowedSecurityKeyNames, QSession qSession, String securityKeyName, JSONObject securityKeyValues, String jsonKey)
|
||||
private void setSecurityKeyValuesFromToken(Set<String> allowedSecurityKeyNames, QSession qSession, String securityKeyName, JSONObject securityKeyValues, String jsonKey)
|
||||
{
|
||||
if(!allowedSecurityKeyNames.contains(securityKeyName))
|
||||
{
|
||||
@ -686,7 +740,7 @@ public class Auth0AuthenticationModule implements QAuthenticationModuleInterface
|
||||
Object optValue = valueArray.opt(i);
|
||||
if(optValue != null)
|
||||
{
|
||||
qSession.withSecurityKeyValue(securityKeyName, ValueUtils.getValueAsString(optValue));
|
||||
addSecurityKeyValueToSession(qSession, securityKeyName, ValueUtils.getValueAsString(optValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -697,7 +751,7 @@ public class Auth0AuthenticationModule implements QAuthenticationModuleInterface
|
||||
{
|
||||
for(String v : values.split(","))
|
||||
{
|
||||
qSession.withSecurityKeyValue(securityKeyName, v);
|
||||
addSecurityKeyValueToSession(qSession, securityKeyName, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -815,6 +869,25 @@ public class Auth0AuthenticationModule implements QAuthenticationModuleInterface
|
||||
**
|
||||
*******************************************************************************/
|
||||
private String getAccessTokenFromSessionUUID(Auth0AuthenticationMetaData metaData, String sessionUUID) throws QAuthenticationException
|
||||
{
|
||||
if(mayMemoize)
|
||||
{
|
||||
return getAccessTokenFromSessionUUIDMemoization.getResultThrowing(sessionUUID, (String x) ->
|
||||
doGetAccessTokenFromSessionUUID(sessionUUID)
|
||||
).orElse(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (doGetAccessTokenFromSessionUUID(sessionUUID));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private String doGetAccessTokenFromSessionUUID(String sessionUUID) throws QAuthenticationException
|
||||
{
|
||||
String accessToken = null;
|
||||
QSession beforeSession = QContext.getQSession();
|
||||
@ -982,4 +1055,39 @@ public class Auth0AuthenticationModule implements QAuthenticationModuleInterface
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
private QAuthenticationModuleCustomizerInterface getCustomizer()
|
||||
{
|
||||
try
|
||||
{
|
||||
if(!customizerHasBeenRequested)
|
||||
{
|
||||
customizerHasBeenRequested = true;
|
||||
|
||||
if(this.metaData == null)
|
||||
{
|
||||
this.metaData = (Auth0AuthenticationMetaData) QContext.getQInstance().getAuthentication();
|
||||
}
|
||||
|
||||
if(this.metaData.getCustomizer() != null)
|
||||
{
|
||||
this._customizer = QCodeLoader.getAdHoc(QAuthenticationModuleCustomizerInterface.class, this.metaData.getCustomizer());
|
||||
}
|
||||
}
|
||||
|
||||
return (this._customizer);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
////////////////////////
|
||||
// should this throw? //
|
||||
////////////////////////
|
||||
LOG.warn("Error getting customizer.", e);
|
||||
return (null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1813,6 +1813,19 @@ class QInstanceValidatorTest extends BaseTest
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
void testAuthenticationCustomizer()
|
||||
{
|
||||
assertValidationSuccess((qInstance -> qInstance.getAuthentication().withCustomizer(null)));
|
||||
assertValidationSuccess((qInstance -> qInstance.getAuthentication().withCustomizer(new QCodeReference(ValidAuthCustomizer.class))));
|
||||
assertValidationFailureReasons((qInstance -> qInstance.getAuthentication().withCustomizer(new QCodeReference(ArrayList.class))), "not of the expected type");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@ -1987,5 +2000,13 @@ class QInstanceValidatorTest extends BaseTest
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static class ValidAuthCustomizer implements QAuthenticationModuleCustomizerInterface {}
|
||||
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
package com.kingsrook.qqq.backend.core.modules.authentication.implementations;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Base64;
|
||||
@ -36,7 +37,9 @@ import com.kingsrook.qqq.backend.core.instances.QMetaDataVariableInterpreter;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.QInstance;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.authentication.Auth0AuthenticationMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.authentication.QAuthenticationMetaData;
|
||||
import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference;
|
||||
import com.kingsrook.qqq.backend.core.model.session.QSession;
|
||||
import com.kingsrook.qqq.backend.core.modules.authentication.QAuthenticationModuleCustomizerInterface;
|
||||
import com.kingsrook.qqq.backend.core.state.InMemoryStateProvider;
|
||||
import com.kingsrook.qqq.backend.core.state.SimpleStateKey;
|
||||
import com.kingsrook.qqq.backend.core.utils.CollectionUtils;
|
||||
@ -354,7 +357,7 @@ public class Auth0AuthenticationModuleTest extends BaseTest
|
||||
"iat": 1673379451
|
||||
}
|
||||
""");
|
||||
Auth0AuthenticationModule.setSecurityKeysInSessionFromJwtPayload(qInstance, payload, qSession);
|
||||
new Auth0AuthenticationModule().setSecurityKeysInSessionFromJwtPayload(qInstance, payload, qSession);
|
||||
assertEquals(List.of("true"), qSession.getSecurityKeyValues("storeAllAccess"));
|
||||
|
||||
/////////////////////////////////////////////
|
||||
@ -373,7 +376,7 @@ public class Auth0AuthenticationModuleTest extends BaseTest
|
||||
"iat": 1673379451
|
||||
}
|
||||
""");
|
||||
Auth0AuthenticationModule.setSecurityKeysInSessionFromJwtPayload(qInstance, payload, qSession);
|
||||
new Auth0AuthenticationModule().setSecurityKeysInSessionFromJwtPayload(qInstance, payload, qSession);
|
||||
assertEquals(List.of("2"), qSession.getSecurityKeyValues("store"));
|
||||
|
||||
//////////////////////////
|
||||
@ -394,7 +397,7 @@ public class Auth0AuthenticationModuleTest extends BaseTest
|
||||
"iat": 1673379451
|
||||
}
|
||||
""");
|
||||
Auth0AuthenticationModule.setSecurityKeysInSessionFromJwtPayload(qInstance, payload, qSession);
|
||||
new Auth0AuthenticationModule().setSecurityKeysInSessionFromJwtPayload(qInstance, payload, qSession);
|
||||
assertEquals(List.of("3", "4", "5"), qSession.getSecurityKeyValues("store"));
|
||||
assertEquals(List.of("internal"), qSession.getSecurityKeyValues("internalOrExternal"));
|
||||
|
||||
@ -409,7 +412,7 @@ public class Auth0AuthenticationModuleTest extends BaseTest
|
||||
"iat": 1673379451
|
||||
}
|
||||
""");
|
||||
Auth0AuthenticationModule.setSecurityKeysInSessionFromJwtPayload(qInstance, payload, qSession);
|
||||
new Auth0AuthenticationModule().setSecurityKeysInSessionFromJwtPayload(qInstance, payload, qSession);
|
||||
assertTrue(CollectionUtils.nullSafeIsEmpty(qSession.getSecurityKeyValues()));
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
@ -428,7 +431,7 @@ public class Auth0AuthenticationModuleTest extends BaseTest
|
||||
"iat": 1673379451
|
||||
}
|
||||
""");
|
||||
Auth0AuthenticationModule.setSecurityKeysInSessionFromJwtPayload(qInstance, payload, qSession);
|
||||
new Auth0AuthenticationModule().setSecurityKeysInSessionFromJwtPayload(qInstance, payload, qSession);
|
||||
assertTrue(CollectionUtils.nullSafeIsEmpty(qSession.getSecurityKeyValues()));
|
||||
}
|
||||
|
||||
@ -491,4 +494,73 @@ public class Auth0AuthenticationModuleTest extends BaseTest
|
||||
assertEquals("123456******", maskForLog("1234567890"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
@Test
|
||||
void testCustomizer()
|
||||
{
|
||||
QInstance qInstance = QContext.getQInstance();
|
||||
qInstance.setAuthentication(new Auth0AuthenticationMetaData()
|
||||
.withCustomizer(new QCodeReference(Customizer.class)));
|
||||
|
||||
{
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// baseline case - value in json becomes value in security key //
|
||||
/////////////////////////////////////////////////////////////////
|
||||
QSession qSession = new QSession();
|
||||
JSONObject payload = new JSONObject("""
|
||||
{
|
||||
"com.kingsrook.qqq.app_metadata": {
|
||||
"securityKeyValues": {
|
||||
"store": "1"
|
||||
}
|
||||
}
|
||||
}
|
||||
""");
|
||||
new Auth0AuthenticationModule().setSecurityKeysInSessionFromJwtPayload(qInstance, payload, qSession);
|
||||
assertEquals(List.of("1"), qSession.getSecurityKeyValues("store"));
|
||||
}
|
||||
|
||||
{
|
||||
QSession qSession = new QSession();
|
||||
JSONObject payload = new JSONObject("""
|
||||
{
|
||||
"com.kingsrook.qqq.app_metadata": {
|
||||
"securityKeyValues": {
|
||||
"store": "oddDigits"
|
||||
}
|
||||
}
|
||||
}
|
||||
""");
|
||||
new Auth0AuthenticationModule().setSecurityKeysInSessionFromJwtPayload(qInstance, payload, qSession);
|
||||
assertEquals(List.of("1", "3", "5", "7", "9"), qSession.getSecurityKeyValues("store"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
*******************************************************************************/
|
||||
public static class Customizer implements QAuthenticationModuleCustomizerInterface
|
||||
{
|
||||
@Override
|
||||
public void addSecurityKeyValueToSession(QSession session, String keyName, Serializable value)
|
||||
{
|
||||
if("oddDigits".equals(value))
|
||||
{
|
||||
for(String oddValue : List.of("1", "3", "5", "7", "9"))
|
||||
{
|
||||
QAuthenticationModuleCustomizerInterface.super.addSecurityKeyValueToSession(session, keyName, oddValue);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QAuthenticationModuleCustomizerInterface.super.addSecurityKeyValueToSession(session, keyName, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user