CB-2127 use same token in additional auth

This commit is contained in:
Alexander Skoblikov
2022-06-29 20:14:10 +03:00
parent e0cfb5e623
commit c194faadd4
2 changed files with 52 additions and 30 deletions
@@ -23,12 +23,14 @@ import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.model.auth.SMAuthInfo;
import org.jkiss.dbeaver.model.auth.SMAuthStatus;
import org.jkiss.dbeaver.model.auth.SMCredentials;
import org.jkiss.dbeaver.model.auth.SMCredentialsProvider;
import org.jkiss.dbeaver.model.exec.DBCException;
import org.jkiss.dbeaver.model.rm.RMController;
import org.jkiss.dbeaver.model.security.SMAdminController;
import org.jkiss.dbeaver.model.security.SMController;
import org.jkiss.utils.CommonUtils;
import java.util.Objects;
import java.util.Set;
@@ -62,18 +64,27 @@ public class WebUserContext implements SMCredentialsProvider {
* @throws DBException - if user already authorized and new token come from another user
*/
public void refresh(SMAuthInfo smAuthInfo) throws DBException {
if (smAuthInfo.getAuthStatus() != SMAuthStatus.SUCCESS) {
throw new DBCException("Authorization did not complete successfully");
}
var isNonAnonymousUserAuthorized = isAuthorizedInSecurityManager() && getUser() != null;
var tokenInfo = smAuthInfo.getAuthPermissions();
if (isNonAnonymousUserAuthorized && !Objects.equals(getUserId(), tokenInfo.getUserId())) {
var authPermissions = smAuthInfo.getAuthPermissions();
if (authPermissions == null) {
throw new DBCException("Required information about session permissions is missing");
}
var isSessionChanged = !CommonUtils.equalObjects(smSessionId, authPermissions.getSessionId());
if (isNonAnonymousUserAuthorized && isSessionChanged && !Objects.equals(getUserId(), authPermissions.getUserId())) {
throw new DBCException("Another user is already logged in");
}
this.smCredentials = new SMCredentials(smAuthInfo.getSmAuthToken(), tokenInfo.getUserId());
this.userPermissions = tokenInfo.getPermissions();
this.smCredentials = new SMCredentials(smAuthInfo.getSmAuthToken(), authPermissions.getUserId());
this.userPermissions = authPermissions.getPermissions();
this.securityController = application.getSecurityController(this);
this.adminSecurityController = application.getAdminSecurityController(this);
this.rmController = application.getResourceController(this);
this.smSessionId = smAuthInfo.getAuthPermissions().getSessionId();
setUser(tokenInfo.getUserId() == null ? null : new WebUser(securityController.getUserById(tokenInfo.getUserId())));
if (isSessionChanged) {
this.smSessionId = smAuthInfo.getAuthPermissions().getSessionId();
setUser(authPermissions.getUserId() == null ? null : new WebUser(securityController.getUserById(authPermissions.getUserId())));
}
}
@@ -961,7 +961,8 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
if (existAuthInfo.getAuthStatus() != SMAuthStatus.IN_PROGRESS) {
throw new SMException("Authorization already finished and cannot be updated");
}
updateAuthStatus(authId, authStatus, authInfo, null, null);
var authSessionInfo = readAuthAttemptSessionInfo(authId);
updateAuthStatus(authId, authStatus, authInfo, null, authSessionInfo.getSmSessionId());
}
private void updateAuthStatus(@NotNull String authId,
@@ -1108,6 +1109,8 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
String userId = null;
var finishAuthMonitor = new VoidProgressMonitor();
AuthAttemptSessionInfo authAttemptSessionInfo = readAuthAttemptSessionInfo(authId);
boolean isMainAuthSession = authAttemptSessionInfo.getSmSessionId() == null;
for (String authProviderId : authProviderIds) {
var userCredentials = (Map<String, Object>) authInfo.getAuthData().get(authProviderId);
var userIdFromCreds = findOrCreateExternalUserByCredentials(
@@ -1115,7 +1118,7 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
authAttemptSessionInfo.getSessionParams(),
userCredentials,
finishAuthMonitor,
authAttemptSessionInfo.getSmSessionId() == null
isMainAuthSession
);
if (userIdFromCreds == null) {
@@ -1126,31 +1129,39 @@ public class CBEmbeddedSecurityController implements SMAdminController, SMAuthen
userId = userIdFromCreds;
}
try (Connection dbCon = database.openConnection()) {
try (JDBCTransaction txn = new JDBCTransaction(dbCon)) {
String smSessionId;
if (authAttemptSessionInfo.getSmSessionId() == null) {
smSessionId = createSmSession(
authAttemptSessionInfo.getAppSessionId(),
userId,
authAttemptSessionInfo.getSessionParams(),
authAttemptSessionInfo.getSessionType(),
dbCon
);
} else {
smSessionId = authAttemptSessionInfo.getSmSessionId();
String token;
SMAuthPermissions permissions;
if (!isMainAuthSession) {
//this is an additional authorization and we should to return the original permissions and userId
token = findTokenBySmSession(authAttemptSessionInfo.getSmSessionId());
permissions = getTokenPermissions(token);
} else {
try (Connection dbCon = database.openConnection()) {
try (JDBCTransaction txn = new JDBCTransaction(dbCon)) {
String smSessionId;
if (authAttemptSessionInfo.getSmSessionId() == null) {
smSessionId = createSmSession(
authAttemptSessionInfo.getAppSessionId(),
userId,
authAttemptSessionInfo.getSessionParams(),
authAttemptSessionInfo.getSessionType(),
dbCon
);
} else {
smSessionId = authAttemptSessionInfo.getSmSessionId();
}
token = generateAuthToken(smSessionId, userId, dbCon);
permissions = new SMAuthPermissions(userId, smSessionId, getUserPermissions(userId));
txn.commit();
}
var token = generateAuthToken(smSessionId, userId, dbCon);
var permissions = getUserPermissions(userId);
txn.commit();
updateAuthStatus(authId, SMAuthStatus.SUCCESS, authInfo.getAuthData(), null, smSessionId);
return SMAuthInfo.success(authId, token, new SMAuthPermissions(userId, smSessionId, permissions), authInfo.getAuthData());
} catch (SQLException e) {
var error = "Error during token generation";
updateAuthStatus(authId, SMAuthStatus.ERROR, authInfo.getAuthData(), error);
throw new SMException(error, e);
}
} catch (SQLException e) {
var error = "Error during token generation";
updateAuthStatus(authId, SMAuthStatus.ERROR, authInfo.getAuthData(), error);
throw new SMException(error, e);
}
updateAuthStatus(authId, SMAuthStatus.SUCCESS, authInfo.getAuthData(), null, permissions.getSessionId());
return SMAuthInfo.success(authId, token, permissions, authInfo.getAuthData());
}
private AuthAttemptSessionInfo readAuthAttemptSessionInfo(@NotNull String authId) throws DBException {