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

Kc change #1062

Merged
merged 18 commits into from
Jun 30, 2021
25 changes: 25 additions & 0 deletions Apromore-Core-Components/Apromore-Portal/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
org.springframework.web.context.request,
org.springframework.web.filter,
org.zkoss.zel.impl,
com.fasterxml.jackson.annotation,
org.zkoss.zk.au.http,
*
</Import-Package>
Expand Down Expand Up @@ -122,6 +123,12 @@
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.22</version>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.10.5</version>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
Expand Down Expand Up @@ -378,6 +385,24 @@
<artifactId>guava</artifactId>
</dependency>

<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-servlet-filter-adapter</artifactId>
<version>14.0.0</version>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update keycloak.version in ApromoreCore/pom.xml and use ${keycloak.version}

<exclusions>
<exclusion> <!-- declare the exclusion here -->
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-osgi-adapter</artifactId>
<version>14.0.0</version>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update keycloak.version in ApromoreCore/pom.xml and use ${keycloak.version}

</dependency>

</dependencies>

</project>

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -21,158 +21,146 @@
*/
package org.apromore.portal.security;

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apromore.plugin.portal.PortalLoggerFactory;
import org.slf4j.Logger;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Base64;
import java.util.UUID;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apromore.plugin.portal.PortalLoggerFactory;
import org.slf4j.Logger;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;

public class KeycloakLoginUrlAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint {

private static final Logger LOGGER = PortalLoggerFactory.getLogger(KeycloakLoginUrlAuthenticationEntryPoint.class);
private static final Logger LOGGER =
PortalLoggerFactory.getLogger(KeycloakLoginUrlAuthenticationEntryPoint.class);

private static final String ENV_KEYCLOAK_REALM_NAME_KEY = "KEYCLOAK_REALM_NAME";
private static final String KEYCLOAK_REALM_PLACEHOLDER = "<keycloakRealm>";
private static final String STATE_UUID_PLACEHOLDER = "<state_uuid>";
private static final String FULL_RETURN_PATH_PLACEHOLDER = "<full_return_path>";
private static final String ENV_KEYCLOAK_REALM_NAME_KEY = "KEYCLOAK_REALM_NAME";
private static final String KEYCLOAK_REALM_PLACEHOLDER = "<keycloakRealm>";
private static final String STATE_UUID_PLACEHOLDER = "<state_uuid>";
private static final String FULL_RETURN_PATH_PLACEHOLDER = "<full_return_path>";

private String fullConfigurableReturnPath = new String(
Base64.getEncoder().encode("http://localhost:8181/".getBytes()));
private boolean utiliseKeycloakSso = false;
private String fullConfigurableReturnPath =
new String(Base64.getEncoder().encode("http://localhost:8181/".getBytes()));
private boolean utiliseKeycloakSso = false;

private String keycloakLoginFormUrl;
private String keycloakLoginFormUrl;

public void setFullProtocolHostPortUrl(final String fullProtocolHostPortUrl) {
fullConfigurableReturnPath = new String(
Base64.getEncoder().encode(fullProtocolHostPortUrl.getBytes()));
public void setFullProtocolHostPortUrl(final String fullProtocolHostPortUrl) {
fullConfigurableReturnPath =
new String(Base64.getEncoder().encode(fullProtocolHostPortUrl.getBytes()));

LOGGER.trace("Set fullConfigurableReturnPath to {}", fullConfigurableReturnPath);
}
LOGGER.trace("Set fullConfigurableReturnPath to {}", fullConfigurableReturnPath);
}

public void setUseKeycloakSso(final boolean useKeycloakSso) {
utiliseKeycloakSso = useKeycloakSso;
public void setUseKeycloakSso(final boolean useKeycloakSso) {
utiliseKeycloakSso = useKeycloakSso;

LOGGER.trace("Set useKeycloakSso to {}", utiliseKeycloakSso);
}
LOGGER.trace("Set useKeycloakSso to {}", utiliseKeycloakSso);
}

public String getKeycloakLoginFormUrl() {
return keycloakLoginFormUrl;
}
public String getKeycloakLoginFormUrl() {
return keycloakLoginFormUrl;
}

public void setKeycloakLoginFormUrl(final String keycloakLoginFormUrl) {
if ((this.keycloakLoginFormUrl == null) ||
(this.keycloakLoginFormUrl.contains(KEYCLOAK_REALM_PLACEHOLDER))) {
final String keycloakRealm = System.getenv(ENV_KEYCLOAK_REALM_NAME_KEY);
LOGGER.trace("FROM environment property keycloakRealm[" + keycloakRealm + "]");
public void setKeycloakLoginFormUrl(final String keycloakLoginFormUrl) {
if ((this.keycloakLoginFormUrl == null)
|| (this.keycloakLoginFormUrl.contains(KEYCLOAK_REALM_PLACEHOLDER))) {
final String keycloakRealm = System.getenv(ENV_KEYCLOAK_REALM_NAME_KEY);
LOGGER.trace("FROM environment property keycloakRealm[" + keycloakRealm + "]");

if (keycloakRealm != null) {
String tmpUrl = keycloakLoginFormUrl;
if (keycloakRealm != null) {
String tmpUrl = keycloakLoginFormUrl;

final String randomStateUuid = UUID.randomUUID().toString();
LOGGER.trace("randomStateUuid: {}", randomStateUuid);
final String randomStateUuid = UUID.randomUUID().toString();
LOGGER.trace("randomStateUuid: {}", randomStateUuid);

tmpUrl = tmpUrl.replaceFirst(KEYCLOAK_REALM_PLACEHOLDER, keycloakRealm);
tmpUrl = tmpUrl.replaceFirst(STATE_UUID_PLACEHOLDER, randomStateUuid);
tmpUrl = tmpUrl.replaceFirst(FULL_RETURN_PATH_PLACEHOLDER, fullConfigurableReturnPath);
LOGGER.trace(">>>>> >>> > tmpUrl=[" + tmpUrl + "]");
tmpUrl = tmpUrl.replaceFirst(KEYCLOAK_REALM_PLACEHOLDER, keycloakRealm);
tmpUrl = tmpUrl.replaceFirst(STATE_UUID_PLACEHOLDER, randomStateUuid);
tmpUrl = tmpUrl.replaceFirst(FULL_RETURN_PATH_PLACEHOLDER, fullConfigurableReturnPath);
LOGGER.trace(">>>>> >>> > tmpUrl=[" + tmpUrl + "]");

this.keycloakLoginFormUrl = tmpUrl;
} else {
LOGGER.trace("Keycloak login realm was null - maybe keycloak feature turned-off? [proceeding]");
}
}
this.keycloakLoginFormUrl = tmpUrl;
} else {
LOGGER.trace(
"Keycloak login realm was null - maybe keycloak feature turned-off? [proceeding]");
}
}

@Override
public void commence(final HttpServletRequest httpServletRequest,
final HttpServletResponse httpServletResponse,
final AuthenticationException authenticationException) throws IOException, ServletException {
final String requestServletPath = httpServletRequest.getServletPath();
final String requestURL = httpServletRequest.getRequestURL().toString();
LOGGER.trace("requestServletPath {}", requestServletPath);
LOGGER.trace("requestURL {}", requestURL);

super.commence(httpServletRequest, httpServletResponse, authenticationException);
}

@Override
protected String buildRedirectUrlToLoginPage(
final HttpServletRequest request,
final HttpServletResponse response,
final AuthenticationException authException) {

return super.buildRedirectUrlToLoginPage(request, response, authException);
}

/**
* Allows sub-classes to modify the login form URL that should be applicable for a given request.
*
* @param httpServletRequest The HTTP servlet request.
* @param httpServletResponse The HTTP servlet response.
* @param exception The exception
*
* @return The formulated URL (cannot be null or empty; defaults to {@link #getLoginFormUrl()}).
*/
@Override
protected String determineUrlToUseForThisRequest(
final HttpServletRequest httpServletRequest,
final HttpServletResponse httpServletResponse,
final AuthenticationException exception) {
if (utiliseKeycloakSso) {
LOGGER.trace("[ Utilising keycloak ]");

final String loginFormPattern = getKeycloakLoginFormUrl();
LOGGER.trace("### loginFormPattern: {}", loginFormPattern);

final String keycloakRealmOfCustomer = System.getenv(ENV_KEYCLOAK_REALM_NAME_KEY);
LOGGER.trace("keycloakRealmOfCustomer {}", keycloakRealmOfCustomer);

String loginUrl = loginFormPattern.replaceAll(KEYCLOAK_REALM_PLACEHOLDER, keycloakRealmOfCustomer);
LOGGER.trace("loginUrl[1] {}", loginUrl);
loginUrl = loginUrl.replaceAll(FULL_RETURN_PATH_PLACEHOLDER, fullConfigurableReturnPath);
LOGGER.trace("loginUrl[2] {}", loginUrl);

LOGGER.trace(">>> Resolved Keycloak loginUrl (via securityms): {}", loginUrl);

return loginUrl;
} else {
LOGGER.trace("[ Keycloak SSO turned off ]");

String requestUriStr = httpServletRequest.getRequestURL().toString().trim();
LOGGER.trace("requestUriStr: {}", requestUriStr);

try {
final URI uri = new URI(requestUriStr);

final String host = uri.getHost();
final String path = uri.getPath();
int port = (uri.getPort() == -1) ? 80 : uri.getPort();
LOGGER.trace("host {} path {} port {}", host, path, port);

if (host.endsWith("/") || ( (port == 80) || (port == 8181)) ) {
if ( (path == null) ||
( ((port == 80) || (port == 8181)) &&
((path != null) ))) {
requestUriStr = uri.resolve("/login.zul").toString();

LOGGER.trace("requestUriStr: {}", requestUriStr);
}
}
} catch (final URISyntaxException use) {
LOGGER.error("Error in parsing uri: {} - stackTrace {}", use.getMessage(),
ExceptionUtils.getStackTrace(use));
}

return requestUriStr;
}
}

@Override
public void commence(final HttpServletRequest httpServletRequest,
final HttpServletResponse httpServletResponse,
final AuthenticationException authenticationException) throws IOException, ServletException {
final String requestServletPath = httpServletRequest.getServletPath();
final String requestURL = httpServletRequest.getRequestURL().toString();
LOGGER.trace("requestServletPath {}", requestServletPath);
LOGGER.trace("requestURL {}", requestURL);

super.commence(httpServletRequest, httpServletResponse, authenticationException);
}

@Override
protected String buildRedirectUrlToLoginPage(final HttpServletRequest request,
final HttpServletResponse response, final AuthenticationException authException) {

return super.buildRedirectUrlToLoginPage(request, response, authException);
}

/**
* Allows sub-classes to modify the login form URL that should be applicable for a given request.
*
* @param httpServletRequest The HTTP servlet request.
* @param httpServletResponse The HTTP servlet response.
* @param exception The exception
*
* @return The formulated URL (cannot be null or empty; defaults to {@link #getLoginFormUrl()}).
*/
@Override
protected String determineUrlToUseForThisRequest(final HttpServletRequest httpServletRequest,
final HttpServletResponse httpServletResponse, final AuthenticationException exception) {
if (utiliseKeycloakSso) {
LOGGER.trace("[ Utilising keycloak ]");

final String loginFormPattern = getKeycloakLoginFormUrl();
LOGGER.trace("### loginFormPattern: {}", loginFormPattern);

final String keycloakRealmOfCustomer = System.getenv(ENV_KEYCLOAK_REALM_NAME_KEY);
LOGGER.trace("keycloakRealmOfCustomer {}", keycloakRealmOfCustomer);

String loginUrl =
loginFormPattern.replaceAll(KEYCLOAK_REALM_PLACEHOLDER, keycloakRealmOfCustomer);
LOGGER.trace("loginUrl[1] {}", loginUrl);
loginUrl = loginUrl.replaceAll(FULL_RETURN_PATH_PLACEHOLDER, fullConfigurableReturnPath);
LOGGER.trace("loginUrl[2] {}", loginUrl);

LOGGER.trace(">>> Resolved Keycloak loginUrl (via securityms): {}", loginUrl);

return loginUrl;
} else {
LOGGER.trace("[ Keycloak SSO turned off ]");

String requestUriStr = httpServletRequest.getRequestURL().toString().trim();
HttpSession session = httpServletRequest.getSession(false);
URI uri = null;
try {
uri = new URI(requestUriStr);
} catch (URISyntaxException e) {
LOGGER.error("Exception " + ExceptionUtils.getStackTrace(e));
raboczi marked this conversation as resolved.
Show resolved Hide resolved
}
if (session == null || session.getAttribute("USER") == null) {
requestUriStr = uri.resolve("/login.zul").toString();
} else {
requestUriStr = uri.resolve("").toString();
}

return requestUriStr;
}
}
}
Loading