Skip to content

Commit

Permalink
Refactored AuthenticatinRealm.doGetAuthenticationInfo of Realms
Browse files Browse the repository at this point in the history
Signed-off-by: Alberto Codutti <alberto.codutti@eurotech.com>
  • Loading branch information
Coduz committed Nov 3, 2021
1 parent 74f8998 commit 293f3ce
Show file tree
Hide file tree
Showing 8 changed files with 523 additions and 332 deletions.
@@ -0,0 +1,62 @@
/*******************************************************************************
* Copyright (c) 2021 Eurotech and/or its affiliates and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Eurotech - initial API and implementation
*******************************************************************************/
package org.eclipse.kapua.commons.logging;

import org.eclipse.kapua.service.account.Account;
import org.eclipse.kapua.service.user.User;
import org.slf4j.MDC;

/**
* Logging {@link MDC} keys.
*
* @see MDC
* @since 1.6.0
*/
public class LoggingMdcKeys {

/**
* Constructor.
*
* @since 1.6.0
*/
private LoggingMdcKeys() {
}

/**
* The {@link Account#getId()}.
*
* @since 1.0.0
*/
public static final String SCOPE_ID = "scopeId";

/**
* The {@link Account#getName()}.
*
* @since 1.0.0
*/
public static final String ACCOUNT_NAME = "scopeName";

/**
* The {@link User#getId()}
*
* @since 1.0.0
*/
public static final String USER_ID = "userId";

/**
* The {@link User#getName()} ()}
*
* @since 1.6.0
*/
public static final String USER_NAME = "userName";
}
Expand Up @@ -13,97 +13,102 @@
*******************************************************************************/
package org.eclipse.kapua.commons.security;

import java.util.concurrent.Callable;

import org.eclipse.kapua.KapuaException;
import org.eclipse.kapua.commons.util.ThrowingRunnable;
import org.eclipse.kapua.model.id.KapuaId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.Callable;

/**
* Kapua security utility to handle the bind/unbind operation of the Kapua session into the thread context.
* Security utilities to handle the {@link KapuaSession}.
*
* @since 1.0
* @since 1.0.0
*/
public class KapuaSecurityUtils {

private static final Logger logger = LoggerFactory.getLogger(KapuaSecurityUtils.class);

public static final String MDC_USER_ID = "userId";
private static final Logger LOG = LoggerFactory.getLogger(KapuaSecurityUtils.class);

private static final ThreadLocal<KapuaSession> THREAD_SESSION = new ThreadLocal<>();

private KapuaSecurityUtils() {
}

/**
* Return the {@link KapuaSession} associated to the current thread session.
* Returns the {@link KapuaSession} associated to the current {@link ThreadLocal}.
*
* @return
* @return The {@link KapuaSession} associated to the current {@link ThreadLocal}.
* @since 1.0.0
*/
public static KapuaSession getSession() {
return THREAD_SESSION.get();
}

/**
* Bound the {@link KapuaSession} to the current thread session.
* Bounds the {@link KapuaSession} to the current {@link ThreadLocal}.
*
* @param session
* @param session The {@link KapuaSession} to the current {@link ThreadLocal}.
* @since 1.0.0
*/
public static void setSession(KapuaSession session) {
THREAD_SESSION.set(session);
}

/**
* Clear the {@link KapuaSession} from the current thread session.
* Clears the {@link KapuaSession} from the current {@link ThreadLocal}.
*
* @since 1.0.0
*/
public static void clearSession() {
THREAD_SESSION.remove();
}

/**
* Execute the {@link Runnable} in a privileged context.<br>
* Trusted mode means that checks for permissions and role will pass.
* Executes the {@link Runnable} in a privileged context.
* <p>
* Trusted mode means that checks for permissions and role will be skipped.
*
* @param runnable
* The {@link ThrowingRunnable} action to be executed.
* @param runnable The {@link ThrowingRunnable} action to be executed.
* @throws KapuaException
* @since 1.0.0
*/
public static void doPrivileged(final ThrowingRunnable runnable) throws KapuaException {
doPrivileged(new Callable<Void>() {

@Override
public Void call() throws Exception {
runnable.run();
return null;
}

doPrivileged((Callable<Void>) () -> {
runnable.run();
return null;
});
}

/**
* Execute the {@link Callable} in a privileged context.<br>
* Trusted mode means that checks for permissions and role will pass.
*
* @param privilegedAction
* The {@link Callable} action to be executed.
* @param privilegedAction The {@link Callable} action to be executed.
* @return The result of the {@link Callable} action.
* @throws KapuaException
* @since 1.0.0
*/
public static <T> T doPrivileged(Callable<T> privilegedAction) throws KapuaException {
// get (and keep) the current session
KapuaSession previousSession = getSession();
KapuaSession currentSession = null;

KapuaSession currentSession;
if (previousSession == null) {
logger.debug("==> create new session");
currentSession = new KapuaSession(null, KapuaId.ONE, KapuaId.ONE);
currentSession.setTrustedMode(true);
LOG.debug("Created a new KapuaSession as ScopeId: {} - UserId: {} - Trusted: {} - Token: {}",
currentSession.getScopeId(),
currentSession.getUserId(),
currentSession.isTrustedMode(),
currentSession.getAccessToken() != null ? currentSession.getAccessToken().getTokenId() : null);
} else {
logger.debug("==> clone from previous session");
currentSession = KapuaSession.createFrom();
LOG.debug("Cloning KapuaSession as ScopeId: {} - UserId: {} - Trusted: {} - Token: {}",
currentSession.getScopeId(),
currentSession.getUserId(),
currentSession.isTrustedMode(),
currentSession.getAccessToken() != null ? currentSession.getAccessToken().getTokenId() : null);
}
setSession(currentSession);

Expand All @@ -114,7 +119,7 @@ public static <T> T doPrivileged(Callable<T> privilegedAction) throws KapuaExcep
} catch (Exception e) {
throw KapuaException.internalError(e);
} finally {
// restore the original session
// Restore the original session.
setSession(previousSession);
}
}
Expand Down
Expand Up @@ -28,6 +28,7 @@
import org.eclipse.kapua.KapuaEntityNotFoundException;
import org.eclipse.kapua.KapuaException;
import org.eclipse.kapua.KapuaRuntimeException;
import org.eclipse.kapua.commons.logging.LoggingMdcKeys;
import org.eclipse.kapua.commons.model.id.KapuaEid;
import org.eclipse.kapua.commons.security.KapuaSecurityUtils;
import org.eclipse.kapua.commons.security.KapuaSession;
Expand All @@ -52,6 +53,7 @@
import org.eclipse.kapua.service.authentication.credential.mfa.MfaOption;
import org.eclipse.kapua.service.authentication.credential.mfa.MfaOptionService;
import org.eclipse.kapua.service.authentication.shiro.exceptions.MfaRequiredException;
import org.eclipse.kapua.service.authentication.shiro.session.ShiroSessionKeys;
import org.eclipse.kapua.service.authentication.shiro.setting.KapuaAuthenticationSetting;
import org.eclipse.kapua.service.authentication.shiro.setting.KapuaAuthenticationSettingKeys;
import org.eclipse.kapua.service.authentication.token.AccessToken;
Expand Down Expand Up @@ -203,8 +205,6 @@ public AccessToken login(LoginCredentials loginCredentials, boolean enableTrust)
accessToken.setTrustKey(trustKey);
}

// Set some logging
MDC.put(KapuaSecurityUtils.MDC_USER_ID, accessToken.getUserId().toCompactId());
LOG.info("Login for thread '{}' - '{}' - '{}'", Thread.currentThread().getId(), Thread.currentThread().getName(), shiroSubject);

} catch (ShiroException se) {
Expand Down Expand Up @@ -256,7 +256,7 @@ public void authenticate(SessionCredentials sessionCredentials) throws KapuaExce

// Set some logging
Subject shiroSubject = SecurityUtils.getSubject();
MDC.put(KapuaSecurityUtils.MDC_USER_ID, accessToken.getUserId().toCompactId());
MDC.put(LoggingMdcKeys.USER_ID, accessToken.getUserId().toCompactId());

LOG.info("Login for thread '{}' - '{}' - '{}'", Thread.currentThread().getId(), Thread.currentThread().getName(), shiroSubject);
} catch (ShiroException se) {
Expand Down Expand Up @@ -523,11 +523,11 @@ private AccessToken createAccessToken(Session session) throws KapuaException {
* @since 1.0
*/
private AccessToken createAccessToken(KapuaEid scopeId, KapuaEid userId) throws KapuaException {

// Retrieve TTL access token
KapuaAuthenticationSetting settings = KapuaAuthenticationSetting.getInstance();
long tokenTtl = settings.getLong(KapuaAuthenticationSettingKeys.AUTHENTICATION_TOKEN_EXPIRE_AFTER);
long refreshTokenTtl = settings.getLong(KapuaAuthenticationSettingKeys.AUTHENTICATION_REFRESH_TOKEN_EXPIRE_AFTER);

// Generate token
Date now = new Date();
String jwt = generateJwt(scopeId, userId, now, tokenTtl);
Expand All @@ -539,6 +539,7 @@ private AccessToken createAccessToken(KapuaEid scopeId, KapuaEid userId) throws
new Date(now.getTime() + tokenTtl),
UUID.randomUUID().toString(),
new Date(now.getTime() + refreshTokenTtl));

AccessToken accessToken;
try {
accessToken = KapuaSecurityUtils.doPrivileged(() -> accessTokenService.create(accessTokenCreator));
Expand All @@ -552,7 +553,15 @@ private AccessToken createAccessToken(KapuaEid scopeId, KapuaEid userId) throws
private void establishSession(Subject subject, AccessToken accessToken, String openIDidToken) {
KapuaSession kapuaSession = new KapuaSession(accessToken, accessToken.getScopeId(), accessToken.getUserId(), openIDidToken);
KapuaSecurityUtils.setSession(kapuaSession);
subject.getSession().setAttribute(KapuaSession.KAPUA_SESSION_KEY, kapuaSession);

Session subjectSession = subject.getSession();
subjectSession.setAttribute(KapuaSession.KAPUA_SESSION_KEY, kapuaSession);

// Set some logging stuff
MDC.put(LoggingMdcKeys.SCOPE_ID, accessToken.getScopeId().toCompactId());
MDC.put(LoggingMdcKeys.ACCOUNT_NAME, (String) subjectSession.getAttribute(ShiroSessionKeys.ACCOUNT_NAME));
MDC.put(LoggingMdcKeys.USER_ID, accessToken.getUserId().toCompactId());
MDC.put(LoggingMdcKeys.USER_NAME, (String) subjectSession.getAttribute(ShiroSessionKeys.USER_NAME));
}

private String generateJwt(KapuaEid scopeId, KapuaEid userId, Date now, long ttl) {
Expand Down

0 comments on commit 293f3ce

Please sign in to comment.