-
Notifications
You must be signed in to change notification settings - Fork 71
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
Kc change #1062
Changes from 11 commits
d59bd32
9b5e97d
3717718
c178cbd
dd2ed30
e070db2
44b8839
349c03f
e3c74b1
285aabb
009641d
a4b5102
80924cd
cc1476f
238ec9e
3d148fa
5129c00
7edfcaa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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> | ||
|
@@ -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> | ||
|
@@ -378,6 +385,24 @@ | |
<artifactId>guava</artifactId> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>org.keycloak</groupId> | ||
<artifactId>keycloak-servlet-filter-adapter</artifactId> | ||
<version>14.0.0</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> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
---|---|---|
|
@@ -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.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 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 keycloakLoginFormUrl; | ||
|
||
public void setFullProtocolHostPortUrl(final String fullProtocolHostPortUrl) { | ||
fullConfigurableReturnPath = new String( | ||
Base64.getEncoder().encode(fullProtocolHostPortUrl.getBytes())); | ||
private static final Logger LOGGER = | ||
PortalLoggerFactory.getLogger(KeycloakLoginUrlAuthenticationEntryPoint.class); | ||
|
||
LOGGER.trace("Set fullConfigurableReturnPath to {}", fullConfigurableReturnPath); | ||
} | ||
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>"; | ||
|
||
public void setUseKeycloakSso(final boolean useKeycloakSso) { | ||
utiliseKeycloakSso = useKeycloakSso; | ||
private String fullConfigurableReturnPath = | ||
new String(Base64.getEncoder().encode("http://localhost:8181/".getBytes())); | ||
private boolean utiliseKeycloakSso = false; | ||
|
||
LOGGER.trace("Set useKeycloakSso to {}", utiliseKeycloakSso); | ||
} | ||
private String keycloakLoginFormUrl; | ||
|
||
public String getKeycloakLoginFormUrl() { | ||
return keycloakLoginFormUrl; | ||
} | ||
public void setFullProtocolHostPortUrl(final String fullProtocolHostPortUrl) { | ||
fullConfigurableReturnPath = | ||
new String(Base64.getEncoder().encode(fullProtocolHostPortUrl.getBytes())); | ||
|
||
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 + "]"); | ||
LOGGER.trace("Set fullConfigurableReturnPath to {}", fullConfigurableReturnPath); | ||
} | ||
|
||
if (keycloakRealm != null) { | ||
String tmpUrl = keycloakLoginFormUrl; | ||
public void setUseKeycloakSso(final boolean useKeycloakSso) { | ||
utiliseKeycloakSso = useKeycloakSso; | ||
|
||
final String randomStateUuid = UUID.randomUUID().toString(); | ||
LOGGER.trace("randomStateUuid: {}", randomStateUuid); | ||
LOGGER.trace("Set useKeycloakSso to {}", utiliseKeycloakSso); | ||
} | ||
|
||
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 + "]"); | ||
public String getKeycloakLoginFormUrl() { | ||
return keycloakLoginFormUrl; | ||
} | ||
|
||
this.keycloakLoginFormUrl = tmpUrl; | ||
} else { | ||
LOGGER.trace("Keycloak login realm was null - maybe keycloak feature turned-off? [proceeding]"); | ||
} | ||
} | ||
} | ||
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 + "]"); | ||
|
||
@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); | ||
if (keycloakRealm != null) { | ||
String tmpUrl = keycloakLoginFormUrl; | ||
|
||
super.commence(httpServletRequest, httpServletResponse, authenticationException); | ||
} | ||
final String randomStateUuid = UUID.randomUUID().toString(); | ||
LOGGER.trace("randomStateUuid: {}", randomStateUuid); | ||
|
||
@Override | ||
protected String buildRedirectUrlToLoginPage( | ||
final HttpServletRequest request, | ||
final HttpServletResponse response, | ||
final AuthenticationException authException) { | ||
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 + "]"); | ||
|
||
return super.buildRedirectUrlToLoginPage(request, response, authException); | ||
this.keycloakLoginFormUrl = tmpUrl; | ||
} else { | ||
LOGGER.trace( | ||
"Keycloak login realm was null - maybe keycloak feature turned-off? [proceeding]"); | ||
} | ||
} | ||
|
||
/** | ||
* 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) { | ||
// TODO Auto-generated catch block | ||
e.printStackTrace(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would be good to log exception as error. |
||
} | ||
if (session == null || session.getAttribute("USER") == null) { | ||
requestUriStr = uri.resolve("/login.zul").toString(); | ||
} else { | ||
requestUriStr = uri.resolve("").toString(); | ||
} | ||
|
||
return requestUriStr; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
/*- | ||
* #%L | ||
* This file is part of "Apromore Core". | ||
* %% | ||
* Copyright (C) 2018 - 2021 Apromore Pty Ltd. | ||
* %% | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU Lesser 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 General Lesser Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Lesser Public | ||
* License along with this program. If not, see | ||
* <http://www.gnu.org/licenses/lgpl-3.0.html>. | ||
* #L% | ||
*/ | ||
package org.apromore.portal.servlet.filter; | ||
|
||
import java.util.Enumeration; | ||
import javax.servlet.FilterConfig; | ||
import javax.servlet.ServletContext; | ||
|
||
public class ApromoreFilterConfig implements FilterConfig { | ||
|
||
ServletContext context; | ||
|
||
|
||
|
||
public ApromoreFilterConfig(ServletContext context) { | ||
this.context = context; | ||
} | ||
|
||
@Override | ||
public String getFilterName() { | ||
// TODO Auto-generated method stub | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Minor] remove auto-generated comments There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will delete this file. Not used |
||
return null; | ||
} | ||
|
||
@Override | ||
public ServletContext getServletContext() { | ||
// TODO Auto-generated method stub | ||
return context; | ||
} | ||
|
||
@Override | ||
public String getInitParameter(String name) { | ||
switch (name) { | ||
case "keycloak.config.skipPattern": | ||
return null; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Minor] remove blank lines |
||
|
||
default: | ||
break; | ||
} | ||
return null; | ||
} | ||
|
||
@Override | ||
public Enumeration<String> getInitParameterNames() { | ||
// TODO Auto-generated method stub | ||
return null; | ||
} | ||
|
||
} |
There was a problem hiding this comment.
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}