Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: In case when Keycloack configured, if you create a user with non-ascii names (first name, last name, e-mail address) then these names will be displayed using non-readable symbols in the list of users in the Administration console. #960

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -132,19 +132,21 @@ private AuthResult doAuth(HttpServletRequest req, HttpServletResponse rsp, Deque
.mput(
Authz.InvokeKeys.QUERY_FLAGS,
Authz.QueryFlags.RESOLVE_GROUPS | Authz.QueryFlags.RESOLVE_GROUPS_RECURSIVE);
if (SsoService.getSsoContext(req)
boolean externalSso = SsoService.getSsoContext(req)
.getSsoLocalConfig()
.getBoolean("ENGINE_SSO_ENABLE_EXTERNAL_SSO")) {
.getBoolean("ENGINE_SSO_ENABLE_EXTERNAL_SSO");
if (externalSso) {
input.put(Authz.InvokeKeys.HTTP_SERVLET_REQUEST, req);
}
ExtMap outputMap = profile.getAuthz().invoke(input);
token = SsoService.getTokenFromHeader(req);
ExtMap principalRecord = outputMap.get(Authz.InvokeKeys.PRINCIPAL_RECORD);
SsoSession ssoSession = SsoService.persistAuthInfoInContextWithToken(req,
token,
null,
profile.getName(),
authRecord,
outputMap.get(Authz.InvokeKeys.PRINCIPAL_RECORD));
SsoService.fixExternalNames(principalRecord, externalSso));
log.info("User {}@{} with profile [{}] successfully logged in with scopes : {} ",
SsoService.getUserId(outputMap.get(Authz.InvokeKeys.PRINCIPAL_RECORD)),
profile.getAuthzName(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.ovirt.engine.api.extensions.ExtKey;
import org.ovirt.engine.api.extensions.ExtMap;
import org.ovirt.engine.api.extensions.aaa.Authn;
import org.ovirt.engine.api.extensions.aaa.Authz;
Expand Down Expand Up @@ -925,4 +926,34 @@ private static Set<String> processGroupMemberships(
}
return membershipIds;
}

/**
* Convert principal record names from ISO_8859_1 to UTF-8 in case when the "External SSO provider" configured
* Apache (httpd) encodes all names using ISO_8859_1 but ovirt-engine tries to work with the data using UTF-8.
* This causes names (like first name, last name, e-mail address) corruption if non-ascii characters are used in
* these names. This routine converts the names to avoid the corruption.
* @param principalRecord Principal Record content to update
* @param externalSso Flag that signals if the "External SSO provider" (Keycloak) configured for the system.
* If the flag is 'false' then no any changes performed.
* @return Updated Principal Record content with fixed names (first name, last name, e-mail address)
*/
public static ExtMap fixExternalNames(ExtMap principalRecord, boolean externalSso) {
if (externalSso && principalRecord != null) {
//If the principal record came from external system, this means it was passed via the mod_auth_openidc
//plugin of the Apache service. This plugin sends all claims using the ISO_8859_1 encoding. This corrupts
//non-ascii characters in names. We need to fix the names:
fixExternalName(principalRecord, Authz.PrincipalRecord.FIRST_NAME);
fixExternalName(principalRecord, Authz.PrincipalRecord.LAST_NAME);
fixExternalName(principalRecord, Authz.PrincipalRecord.EMAIL);
}
return principalRecord;
}

private static void fixExternalName(ExtMap principalRecord, ExtKey key) {
String value = principalRecord.get(key);
if (value != null) {
String valueFixed = new String(value.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
principalRecord.put(key, valueFixed);
}
}
}