Initial commit for AAI-UI(sparky-backend)
[aai/sparky-be.git] / src / main / java / org / openecomp / sparky / security / filter / LoginFilter.java
1 /**
2  * ============LICENSE_START===================================================
3  * SPARKY (AAI UI service)
4  * ============================================================================
5  * Copyright © 2017 AT&T Intellectual Property.
6  * Copyright © 2017 Amdocs
7  * All rights reserved.
8  * ============================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ============LICENSE_END=====================================================
21  *
22  * ECOMP and OpenECOMP are trademarks
23  * and service marks of AT&T Intellectual Property.
24  */
25
26 package org.openecomp.sparky.security.filter;
27
28 import java.io.IOException;
29
30 import javax.servlet.Filter;
31 import javax.servlet.FilterChain;
32 import javax.servlet.FilterConfig;
33 import javax.servlet.ServletException;
34 import javax.servlet.ServletRequest;
35 import javax.servlet.ServletResponse;
36 import javax.servlet.http.Cookie;
37 import javax.servlet.http.HttpServletRequest;
38 import javax.servlet.http.HttpServletResponse;
39 import javax.servlet.http.HttpSession;
40 import javax.ws.rs.core.HttpHeaders;
41
42 import org.openecomp.cl.api.Logger;
43 import org.openecomp.cl.eelf.LoggerFactory;
44 import org.openecomp.portalsdk.core.onboarding.listener.PortalTimeoutHandler;
45 import org.openecomp.portalsdk.core.onboarding.util.PortalApiConstants;
46 import org.openecomp.portalsdk.core.onboarding.util.PortalApiProperties;
47 import org.openecomp.portalsdk.core.onboarding.util.SSOUtil;
48 import org.openecomp.sparky.logging.AaiUiMsgs;
49 import org.openecomp.sparky.security.EcompSso;
50 import org.openecomp.sparky.security.portal.config.PortalAuthenticationConfig;
51
52 /**
53  * This filter checks every request for proper ECOMP Portal single sign on initialization. The
54  * possible paths and actions:
55  * <OL>
56  * <LI>User starts at an app page via a bookmark. No ECOMP portal cookie is set. Redirect there to
57  * get one; then continue as below.
58  * <LI>User starts at ECOMP Portal and goes to app. Alternately, the user's session times out and
59  * the user hits refresh. The ECOMP Portal cookie is set, but there is no valid session. Create one
60  * and publish info.
61  * <LI>User has valid ECOMP Portal cookie and session. Reset the max idle in that session.
62  * </OL>
63  * <P>
64  * Notes:
65  * <UL>
66  * <LI>Portal Session should be up prior to App Session</LI>
67  * <LI>If App Session Expires or if EPService cookie is unavailable, we need to redirect to Portal.
68  * <LI>Method {@link #initiateSessionMgtHandler(HttpServletRequest)} should be called for Session
69  * management when the initial session is created
70  * <LI>While redirecting, the cookie "redirectUrl" should also be set so that Portal knows where to
71  * forward the request to once the Portal Session is created and EPService cookie is set.
72  * <LI>Method {@link #resetSessionMaxIdleTimeOut(HttpServletRequest)} should be called for every
73  * request to reset the MaxInactiveInterval to the right value.
74  * </UL>
75  * <P>
76  * This filter incorporates most features of the SDK application's SessionTimeoutInterceptor and
77  * SingleSignOnController classes
78  */
79 public class LoginFilter implements Filter {
80
81   private static final Logger LOG = LoggerFactory.getInstance().getLogger(LoginFilter.class);
82
83   @Override
84   public void init(FilterConfig filterConfig) throws ServletException {
85     // Validate that app has provided useful portal properties
86     if (PortalApiProperties.getProperty(PortalApiConstants.ECOMP_REDIRECT_URL) == null) {
87       throw new ServletException("Failed to find URL in portal.properties");
88     }
89
90     PortalAuthenticationConfig appProperties;
91     try {
92       appProperties = PortalAuthenticationConfig.getInstance();
93     } catch (Exception ex) {
94       throw new ServletException("Failed to get properties", ex);
95     }
96
97     String restUser = appProperties.getUsername();
98     String restPassword = appProperties.getPassword();
99     if (restUser == null || restPassword == null) {
100       throw new ServletException("Failed to find user and/or password from properties");
101     }
102   }
103
104   @Override
105   public void destroy() {
106     // No resources to release
107   }
108
109   /*
110    * (non-Javadoc)
111    *
112    * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse,
113    * javax.servlet.FilterChain)
114    */
115   @Override
116   public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
117       throws ServletException, IOException {
118     HttpServletRequest request = (HttpServletRequest) req;
119     HttpServletResponse response = (HttpServletResponse) res;
120
121     // Choose authentication appropriate for the request.
122     final String restApiURI = request.getContextPath() + PortalApiConstants.API_PREFIX;
123     if (request.getRequestURI().startsWith(restApiURI)) {
124       // REST servlet checks credentials
125       LOG.debug(AaiUiMsgs.LOGIN_FILTER_DEBUG, "doFilter: delegating auth to REST servlet for request " + request.getRequestURI());
126       chain.doFilter(request, response);
127     } else {
128       // All other requests require ECOMP Portal authentication
129       if (EcompSso.validateEcompSso(request) == null) {
130         String redirectURL, logMessage;
131
132         // Redirect to Portal UI
133         redirectURL = PortalApiProperties.getProperty(PortalApiConstants.ECOMP_REDIRECT_URL);
134         logMessage = "Unauthorized login attempt.";
135         
136         LOG.debug(AaiUiMsgs.LOGIN_FILTER_DEBUG,
137             logMessage + 
138             " | Remote IP: " + request.getRemoteAddr() + 
139             " | User agent: " + request.getHeader(HttpHeaders.USER_AGENT) + 
140             " | Request URL: " + request.getRequestURL() +
141             " | Redirecting to: " + redirectURL); 
142         
143         response.sendRedirect(redirectURL);
144       } else {
145         HttpSession session = request.getSession(false);
146         if (session == null) {
147           // New session
148           session = request.getSession(true);
149           LOG.debug(AaiUiMsgs.LOGIN_FILTER_DEBUG, "doFilter: created new session " + session.getId());
150           initiateSessionMgtHandler(request);
151         } else {
152           // Existing session
153           LOG.debug(AaiUiMsgs.LOGIN_FILTER_DEBUG, "doFilter: resetting idle in existing session " + session.getId());
154           resetSessionMaxIdleTimeOut(request);
155         }
156         // Pass request back down the filter chain
157         chain.doFilter(request, response);
158       }
159     }
160   }
161
162   /**
163    * Publishes information about the session.
164    *
165    * @param request
166    */
167   private void initiateSessionMgtHandler(HttpServletRequest request) {
168     String portalJSessionId = getPortalJSessionId(request);
169     String jSessionId = getJessionId(request);
170     storeMaxInactiveTime(request);
171     PortalTimeoutHandler.sessionCreated(portalJSessionId, jSessionId, request.getSession(false));
172   }
173
174   /**
175    * Gets the ECOMP Portal service cookie value.
176    *
177    * @param request
178    * @return Cookie value, or null if not found.
179    */
180   private String getPortalJSessionId(HttpServletRequest request) {
181     Cookie ep = EcompSso.getCookie(request, EcompSso.EP_SERVICE);
182     return ep == null ? null : ep.getValue();
183   }
184
185   /**
186    * Gets the container session ID.
187    *
188    * @param request
189    * @return Session ID, or null if no session.
190    */
191   private String getJessionId(HttpServletRequest request) {
192     HttpSession session = request.getSession();
193     return session == null ? null : session.getId();
194   }
195
196   /**
197    * Sets the global session's max idle time to the session's max inactive interval.
198    *
199    * @param request
200    */
201   private void storeMaxInactiveTime(HttpServletRequest request) {
202     HttpSession session = request.getSession(false);
203     if (session != null
204         && session.getAttribute(PortalApiConstants.GLOBAL_SESSION_MAX_IDLE_TIME) == null) {
205       session.setAttribute(PortalApiConstants.GLOBAL_SESSION_MAX_IDLE_TIME,
206           session.getMaxInactiveInterval());
207     }
208   }
209
210   /**
211    * Sets the session's max inactive interval.
212    *
213    * @param request
214    */
215   private void resetSessionMaxIdleTimeOut(HttpServletRequest request) {
216     try {
217       HttpSession session = request.getSession(false);
218       if (session != null) {
219         final Object maxIdleAttribute = session
220             .getAttribute(PortalApiConstants.GLOBAL_SESSION_MAX_IDLE_TIME);
221         if (maxIdleAttribute != null) {
222           session.setMaxInactiveInterval(Integer.parseInt(maxIdleAttribute.toString()));
223         }
224       }
225     } catch (Exception e) {
226       LOG.info(AaiUiMsgs.LOGIN_FILTER_INFO, "resetSessionMaxIdleTimeOut: failed to set session max inactive interval - " + e.getLocalizedMessage());
227     }
228   }
229
230 }