X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=webapp-backend%2Fsrc%2Fmain%2Fjava%2Forg%2Foransc%2Fric%2Fportal%2Fdashboard%2Fportalapi%2FPortalAuthenticationFilter.java;h=50f5b8942c80c3cff3bd101ad33e7972ebd7da6f;hb=9fef9615bd5889eacbe8ddad454b7ff4b4c195c0;hp=2ec5938d8e9317c8f160b094931bbab9dd3468a0;hpb=3f812ea25d352ec33d07f5ffa4c2aa2a77e8e793;p=portal%2Fric-dashboard.git diff --git a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/portalapi/PortalAuthenticationFilter.java b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/portalapi/PortalAuthenticationFilter.java index 2ec5938d..50f5b894 100644 --- a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/portalapi/PortalAuthenticationFilter.java +++ b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/portalapi/PortalAuthenticationFilter.java @@ -20,9 +20,11 @@ package org.oransc.ric.portal.dashboard.portalapi; import java.io.IOException; +import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.lang.invoke.MethodHandles; import java.net.URLEncoder; +import java.util.HashSet; import javax.servlet.Filter; import javax.servlet.FilterChain; @@ -36,11 +38,14 @@ import javax.servlet.http.HttpServletResponse; 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.oransc.ric.portal.dashboard.DashboardConstants; import org.oransc.ric.portal.dashboard.model.EcompUserDetails; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.http.MediaType; +import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; @@ -73,15 +78,39 @@ public class PortalAuthenticationFilter implements Filter { private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + // Unfortunately these names are not available as constants + private static final String[] securityPropertyFiles = { "ESAPI.properties", "key.properties", "portal.properties", + "validation.properties" }; + public static final String REDIRECT_URL_KEY = "redirectUrl"; + private final boolean enforcePortalSecurity; private final PortalAuthManager authManager; private final DashboardUserManager userManager; - public PortalAuthenticationFilter(PortalAuthManager authManager, DashboardUserManager userManager) { + public PortalAuthenticationFilter(boolean portalSecurity, PortalAuthManager authManager, + DashboardUserManager userManager) { + this.enforcePortalSecurity = portalSecurity; this.authManager = authManager; this.userManager = userManager; + if (portalSecurity) { + // Throw if security is requested and prerequisites are not met + for (String pf : securityPropertyFiles) { + InputStream in = MethodHandles.lookup().lookupClass().getClassLoader().getResourceAsStream(pf); + if (in == null) { + String msg = "Failed to find property file on classpath: " + pf; + logger.error(msg); + throw new RuntimeException(msg); + } else { + try { + in.close(); + } catch (IOException ex) { + logger.warn("Failed to close stream", ex); + } + } + } + } } @Override @@ -100,23 +129,69 @@ public class PortalAuthenticationFilter implements Filter { } /** - * Checks for valid cookies and allows request to be served if found; redirects - * to Portal otherwise. Requests for pages ignored in the web security config do - * not hit this filter. + * Requests for pages ignored in the web security config do not hit this filter. */ @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { - logger.debug("doFilter {}", req); + if (enforcePortalSecurity) + doFilterEPSDKFW(req, res, chain); + else + doFilterMockUserAdminRole(req, res, chain); + } + + /* + * Populates security context with a mock user in the admin role. + * + */ + private void doFilterMockUserAdminRole(ServletRequest req, ServletResponse res, FilterChain chain) + throws IOException, ServletException { + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); + if (auth == null || auth.getAuthorities().isEmpty()) { + if (logger.isDebugEnabled()) { + logger.debug("doFilter adding auth to request URI {}", + (req instanceof HttpServletRequest) ? ((HttpServletRequest) req).getRequestURL() : req); + } + EcompRole admin = new EcompRole(); + admin.setId(1L); + admin.setName(DashboardConstants.ROLE_ADMIN); + HashSet roles = new HashSet<>(); + roles.add(admin); + EcompUser user = new EcompUser(); + user.setLoginId("fakeLoginId"); + user.setRoles(roles); + user.setActive(true); + EcompUserDetails userDetails = new EcompUserDetails(user); + PreAuthenticatedAuthenticationToken authToken = new PreAuthenticatedAuthenticationToken(userDetails, + "fakeCredentials", userDetails.getAuthorities()); + SecurityContextHolder.getContext().setAuthentication(authToken); + } else { + logger.debug("doFilter: authorities {}", auth.getAuthorities()); + } + chain.doFilter(req, res); + } + + /* + * Checks for valid cookies and allows request to be served if found; redirects + * to Portal otherwise. + */ + private void doFilterEPSDKFW(ServletRequest req, ServletResponse res, FilterChain chain) + throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; + if (logger.isTraceEnabled()) + logger.trace("doFilter: req {}", request.getRequestURI()); // Need to authenticate the request final String userId = authManager.valdiateEcompSso(request); final EcompUser ecompUser = (userId == null ? null : userManager.getUser(userId)); if (userId == null || ecompUser == null) { - String redirectURL = buildLoginPageUrl(request); - logger.trace("doFilter: unauthorized, redirecting to {}", redirectURL); - response.sendRedirect(redirectURL); + logger.debug("doFilter: unauthorized user requests URI {}, serving login page", request.getRequestURI()); + StringBuffer sb = request.getRequestURL(); + sb.append(request.getQueryString() == null ? "" : "?" + request.getQueryString()); + String body = generateLoginRedirectPage(sb.toString()); + response.setContentType(MediaType.TEXT_HTML_VALUE); + response.getWriter().print(body); + response.getWriter().flush(); } else { EcompUserDetails userDetails = new EcompUserDetails(ecompUser); // Using portal session as credentials is a hack @@ -128,19 +203,44 @@ public class PortalAuthenticationFilter implements Filter { } } - private String buildLoginPageUrl(HttpServletRequest request) { - logger.trace("buildLoginPageUrl"); - // Why so much work to recover the original request? - final StringBuffer sb = request.getRequestURL(); - sb.append(request.getQueryString() == null ? "" : "?" + request.getQueryString()); - final String requestedUrl = sb.toString(); - String encodedUrl = null; - try { - encodedUrl = URLEncoder.encode(requestedUrl, "UTF-8"); - } catch (UnsupportedEncodingException ex) { - logger.error("buildLoginPageUrl: Failed to encode {}", requestedUrl); - } - return DashboardConstants.LOGIN_PAGE + "?" + REDIRECT_URL_KEY + "=" + encodedUrl; + /** + * Generates a page with text only, absolutely no references to any webapp + * resources, so this can be served to an unauthenticated user without + * triggering a new authentication attempt. The page has a link to the Portal + * URL from configuration, with a return URL that is the original request. + * + * @param appUrl + * Original requested URL + * @return HTML + * @throws UnsupportedEncodingException + * On error + */ + private static String generateLoginRedirectPage(String appUrl) throws UnsupportedEncodingException { + String encodedAppUrl = URLEncoder.encode(appUrl, "UTF-8"); + String portalBaseUrl = PortalApiProperties.getProperty(PortalApiConstants.ECOMP_REDIRECT_URL); + String redirectUrl = portalBaseUrl + "?" + PortalAuthenticationFilter.REDIRECT_URL_KEY + "=" + encodedAppUrl; + String aHref = ""; + // If only Java had "here" documents. + String body = String.join(// + System.getProperty("line.separator"), // + "", // + "", // + "RIC Dashboard", // + "", // + "", // + "", // + "

RIC Dashboard

", // + "

Please log in.

", // + "

", // + aHref, "Click here to authenticate at the ONAP Portal", // + "

", // + "", // + ""); + return body; } /**