From 57e7ef7a5b1a20b6237c78f3a85a9b4bb5aefa54 Mon Sep 17 00:00:00 2001 From: "Rogers, Reneal(rr267j)" Date: Mon, 31 Dec 2018 13:01:54 -0500 Subject: [PATCH] fix backdoor issue when using portal Issue-ID: AAI-2045 Change-Id: I7bad950ca142e81ef5f2a698dcaff90975f944a2 Signed-off-by: renealr --- .../config/portal/portal-authentication.properties | 3 +- .../org/onap/aai/sparky/security/EcompSso.java | 39 ++++++++++++++++++-- .../aai/sparky/security/filter/LoginFilter.java | 13 +++---- .../portal/PortalRestAPICentralServiceImpl.java | 17 ++++++--- .../portal/config/PortalAuthenticationConfig.java | 42 ++++++++++++++++------ .../org/onap/aai/sparky/security/EcompSsoTest.java | 36 +++++++++++++++++++ 6 files changed, 125 insertions(+), 25 deletions(-) create mode 100644 sparkybe-onap-service/src/test/java/org/onap/aai/sparky/security/EcompSsoTest.java diff --git a/sparkybe-onap-application/config/portal/portal-authentication.properties b/sparkybe-onap-application/config/portal/portal-authentication.properties index 41c25a6..5b27cc9 100644 --- a/sparkybe-onap-application/config/portal/portal-authentication.properties +++ b/sparkybe-onap-application/config/portal/portal-authentication.properties @@ -2,4 +2,5 @@ username=admin password=OBF:1y0q1uvc1uum1uvg1pil1pjl1uuq1uvk1uuu1y10 onap_enabled=true onap.user_id_cookie_name=UserId -cookie_decryptor_classname=org.onap.aai.sparky.security.BaseCookieDecryptor \ No newline at end of file +cookie_decryptor_classname=org.onap.aai.sparky.security.BaseCookieDecryptor +app_roles=ui_view \ No newline at end of file diff --git a/sparkybe-onap-service/src/main/java/org/onap/aai/sparky/security/EcompSso.java b/sparkybe-onap-service/src/main/java/org/onap/aai/sparky/security/EcompSso.java index 51ac4d5..0bfaca5 100644 --- a/sparkybe-onap-service/src/main/java/org/onap/aai/sparky/security/EcompSso.java +++ b/sparkybe-onap-service/src/main/java/org/onap/aai/sparky/security/EcompSso.java @@ -20,16 +20,20 @@ */ package org.onap.aai.sparky.security; +import java.util.ArrayList; +import java.util.List; + import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import org.onap.aai.cl.api.Logger; import org.onap.aai.cl.eelf.LoggerFactory; import org.onap.aai.sparky.logging.AaiUiMsgs; +import org.onap.aai.sparky.security.portal.PortalRestAPICentralServiceImpl; import org.onap.aai.sparky.security.portal.config.PortalAuthenticationConfig; -import org.onap.portalsdk.core.onboarding.exception.CipherUtilException; -import org.onap.portalsdk.core.onboarding.util.CipherUtil; +import org.onap.portalsdk.core.onboarding.exception.PortalAPIException; import org.onap.portalsdk.core.onboarding.util.PortalApiProperties; +import org.onap.portalsdk.core.restful.domain.EcompRole; /** * Provides authentication services for onboarded ECOMP applications. @@ -40,6 +44,8 @@ public class EcompSso { public static final String CSP_COOKIE_NAME = "csp_cookie_name"; public static final String CSP_GATE_KEEPER_PROD_KEY = "csp_gate_keeper_prod_key"; public static final String ONAP_ENABLED = "ONAP_ENABLED"; + private static EcompSso eCompSso = new EcompSso(); + private PortalRestAPICentralServiceImpl portalRestCentralImpl = new PortalRestAPICentralServiceImpl(); private static final Logger LOG = LoggerFactory.getInstance().getLogger(EcompSso.class); /** @@ -104,6 +110,11 @@ public class EcompSso { "getLoginIdFromCookie failed " + t.getLocalizedMessage()); } } + boolean validated = eCompSso.validateUserAccess(uid); + if (!validated) { + LOG.debug(AaiUiMsgs.DEBUG_GENERIC, "Unable to grant user access to application"); + return null; + } return uid; } @@ -140,4 +151,28 @@ public class EcompSso { return null; } + + public boolean validateUserAccess(String uid) { + boolean hasAccess = false; + ArrayList appRoles = PortalAuthenticationConfig.getInstance().getAppRoles(); + if (uid != null) { + List userRoles = null; + try { + userRoles = portalRestCentralImpl.getUserRoles(uid); + } catch (PortalAPIException e) { + LOG.error(AaiUiMsgs.ERROR_GENERIC, "Unable to get user roles from Portal"); + } + if (userRoles == null || appRoles.isEmpty()) { + LOG.debug(AaiUiMsgs.DEBUG_GENERIC, " Role list is either null or empty"); + return hasAccess; + } else { + for (EcompRole userRole : userRoles) { + if (appRoles.contains(userRole.getName())) { + hasAccess = true; + } + } + } + } + return hasAccess; + } } diff --git a/sparkybe-onap-service/src/main/java/org/onap/aai/sparky/security/filter/LoginFilter.java b/sparkybe-onap-service/src/main/java/org/onap/aai/sparky/security/filter/LoginFilter.java index 5599384..c31cf5b 100644 --- a/sparkybe-onap-service/src/main/java/org/onap/aai/sparky/security/filter/LoginFilter.java +++ b/sparkybe-onap-service/src/main/java/org/onap/aai/sparky/security/filter/LoginFilter.java @@ -127,17 +127,18 @@ public class LoginFilter implements Filter { // Redirect to Portal UI redirectURL = PortalApiProperties.getProperty(PortalApiConstants.ECOMP_REDIRECT_URL); logMessage = "Unauthorized login attempt."; - + LOG.debug(AaiUiMsgs.LOGIN_FILTER_DEBUG, - logMessage + - " | Remote IP: " + request.getRemoteAddr() + - " | User agent: " + request.getHeader(HttpHeaders.USER_AGENT) + + logMessage + + " | Remote IP: " + request.getRemoteAddr() + + " | User agent: " + request.getHeader(HttpHeaders.USER_AGENT) + " | Request URL: " + request.getRequestURL() + - " | Redirecting to: " + redirectURL); - + " | Redirecting to: " + redirectURL); + response.sendRedirect(redirectURL); } else { HttpSession session = request.getSession(false); + response.addHeader("Cache-Control", "no-cache, no-store"); if (session == null) { // New session session = request.getSession(true); diff --git a/sparkybe-onap-service/src/main/java/org/onap/aai/sparky/security/portal/PortalRestAPICentralServiceImpl.java b/sparkybe-onap-service/src/main/java/org/onap/aai/sparky/security/portal/PortalRestAPICentralServiceImpl.java index 032d3ac..922597d 100644 --- a/sparkybe-onap-service/src/main/java/org/onap/aai/sparky/security/portal/PortalRestAPICentralServiceImpl.java +++ b/sparkybe-onap-service/src/main/java/org/onap/aai/sparky/security/portal/PortalRestAPICentralServiceImpl.java @@ -37,6 +37,9 @@ import org.onap.portalsdk.core.onboarding.crossapi.IPortalRestAPIService; import org.onap.portalsdk.core.onboarding.crossapi.IPortalRestCentralService; import org.onap.portalsdk.core.onboarding.exception.PortalAPIException; import org.onap.portalsdk.core.onboarding.rest.RestWebServiceClient; +import org.onap.portalsdk.core.onboarding.util.AuthUtil; +import org.onap.portalsdk.core.onboarding.util.PortalApiConstants; +import org.onap.portalsdk.core.onboarding.util.PortalApiProperties; import org.onap.portalsdk.core.restful.domain.EcompRole; import org.onap.portalsdk.core.restful.domain.EcompUser; import org.slf4j.Logger; @@ -233,11 +236,15 @@ public class PortalRestAPICentralServiceImpl @Override public boolean isAppAuthenticated(HttpServletRequest request) throws PortalAPIException { LOG.debug("Authentication request"); - PortalAuthenticationConfig config = PortalAuthenticationConfig.getInstance(); - String restUsername = request.getHeader(PortalAuthenticationConfig.PROP_USERNAME); - String restPassword = request.getHeader(PortalAuthenticationConfig.PROP_PASSWORD); - return restUsername != null && restPassword != null && restUsername.equals(config.getUsername()) - && restPassword.equals(config.getPassword()); + String nameSpace = PortalApiProperties.getProperty(PortalApiConstants.AUTH_NAMESPACE); + boolean accessAllowed = false; + try { + accessAllowed = AuthUtil.isAccessAllowed(request, nameSpace); + } catch (Exception e) { + String response = "PortalRestAPICentralServiceImpl.isAppAuthenticated failed"; + LOG.error(response, e); + } + return accessAllowed; } diff --git a/sparkybe-onap-service/src/main/java/org/onap/aai/sparky/security/portal/config/PortalAuthenticationConfig.java b/sparkybe-onap-service/src/main/java/org/onap/aai/sparky/security/portal/config/PortalAuthenticationConfig.java index a55fa4c..da1a7d3 100644 --- a/sparkybe-onap-service/src/main/java/org/onap/aai/sparky/security/portal/config/PortalAuthenticationConfig.java +++ b/sparkybe-onap-service/src/main/java/org/onap/aai/sparky/security/portal/config/PortalAuthenticationConfig.java @@ -21,6 +21,8 @@ package org.onap.aai.sparky.security.portal.config; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Properties; import org.onap.aai.cl.api.Logger; @@ -43,6 +45,7 @@ public class PortalAuthenticationConfig { private String userIdCookieName; private CookieDecryptor cookieDecryptor; private String cookieDecryptorClassName; + private String delimitedAppRoles; public static final String PROP_USERNAME = "username"; public static final String PROP_PASSWORD = "password"; // NOSONAR @@ -50,6 +53,7 @@ public class PortalAuthenticationConfig { public static final String PROP_USERID_COOKIE_NAME = "onap.user_id_cookie_name"; // NOSONAR private static final String AUTHENTICATION_CONFIG_FILE = SparkyConstants.PORTAL_AUTHENTICATION_FILE_LOCATION; public static final String PROP_COOKIEDECRYPTORCLASSNAME = "cookie_decryptor_classname"; + public static final String PROP_APP_ROLES = "app_roles"; private static final Logger LOG = LoggerFactory.getInstance().getLogger(PortalAuthenticationConfig.class); private PortalAuthenticationConfig() { @@ -113,17 +117,33 @@ public class PortalAuthenticationConfig { isOnapEnabled = Boolean.parseBoolean(props.getProperty(PROP_IS_ONAP_ENABLED, "true")); userIdCookieName = props.getProperty(PROP_USERID_COOKIE_NAME); cookieDecryptorClassName= props.getProperty(PROP_COOKIEDECRYPTORCLASSNAME); + delimitedAppRoles = props.getProperty(PROP_APP_ROLES); } - - public CookieDecryptor getCookieDecryptor() throws ClassNotFoundException{ - - Class cookieDecrypterClass = Class.forName(cookieDecryptorClassName); - try { - cookieDecryptor = (CookieDecryptor) cookieDecrypterClass.newInstance(); - } catch (InstantiationException | IllegalAccessException e) { - LOG.error(AaiUiMsgs.DECRYPTION_ERROR,"Unable to instantiate Cookie Decryptor Class"); - } - return cookieDecryptor; + + public CookieDecryptor getCookieDecryptor() throws ClassNotFoundException { + + Class cookieDecrypterClass = Class.forName(cookieDecryptorClassName); + try { + cookieDecryptor = (CookieDecryptor) cookieDecrypterClass.newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + LOG.error(AaiUiMsgs.DECRYPTION_ERROR, "Unable to instantiate Cookie Decryptor Class"); + } + return cookieDecryptor; } - + + public ArrayList getAppRoles() { + + ArrayList appRoles = null; + if (delimitedAppRoles == null) { + return new ArrayList<>(); + } + + try { + appRoles = new ArrayList(Arrays.asList(delimitedAppRoles.split(","))); + } catch (Exception exc) { + appRoles = new ArrayList<>(); + } + return appRoles; + } + } \ No newline at end of file diff --git a/sparkybe-onap-service/src/test/java/org/onap/aai/sparky/security/EcompSsoTest.java b/sparkybe-onap-service/src/test/java/org/onap/aai/sparky/security/EcompSsoTest.java new file mode 100644 index 0000000..1863eb9 --- /dev/null +++ b/sparkybe-onap-service/src/test/java/org/onap/aai/sparky/security/EcompSsoTest.java @@ -0,0 +1,36 @@ +package org.onap.aai.sparky.security; + +import static org.junit.Assert.assertNotNull; + +import java.util.ArrayList; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; +import org.onap.aai.sparky.security.portal.PortalRestAPICentralServiceImpl; +import org.onap.portalsdk.core.onboarding.exception.PortalAPIException; +import org.onap.portalsdk.core.restful.domain.EcompRole; + + +public class EcompSsoTest { + + private EcompSso ecompSso; + private PortalRestAPICentralServiceImpl portalRestCentralServiceImpl; + + @Before + public void init() throws Exception { + ecompSso = new EcompSso(); + portalRestCentralServiceImpl = Mockito.mock(PortalRestAPICentralServiceImpl.class); + } + + + @Test + public void TestValidateUserAccess() throws PortalAPIException { + + Mockito.when(portalRestCentralServiceImpl.getUserRoles(Mockito.anyString())) + .thenReturn(new ArrayList()); + assertNotNull(ecompSso.validateUserAccess("ui_view")); + } + + +} -- 2.16.6