/* * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except * in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.wso2.carbon.identity.application.authentication.framework.inbound; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import org.wso2.carbon.identity.application.authentication.framework.exception.FrameworkException; import org.wso2.carbon.identity.application.authentication.framework.internal.FrameworkServiceDataHolder; import org.wso2.carbon.identity.application.authentication.framework.util.FrameworkConstants; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; import java.util.Map; public class CommonInboundAuthenticationServlet extends HttpServlet { private InboundAuthenticationManager inboundAuthenticationManager = new InboundAuthenticationManager(); /** * Get Inbound authentication request builder * * @param req Http request * @param resp Http response * @return Inbound authentication request builder * @throws AuthenticationFrameworkRuntimeException */ private InboundAuthenticationRequestBuilder getInboundRequestBuilder(HttpServletRequest req, HttpServletResponse resp) throws AuthenticationFrameworkRuntimeException { List<InboundAuthenticationRequestBuilder> requestBuilders = FrameworkServiceDataHolder.getInstance() .getInboundAuthenticationRequestBuilders(); for (InboundAuthenticationRequestBuilder requestBuilder : requestBuilders) { if (requestBuilder.canHandle(req, resp)) { return requestBuilder; } } return null; } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { doProcess(request, response); } catch (AuthenticationFrameworkRuntimeException ex) { throw new ServletException(ex); } } /** * Process authentication request/response * * @param request Http request * @param response Http response * @throws AuthenticationFrameworkRuntimeException */ private void doProcess(HttpServletRequest request, HttpServletResponse response) throws AuthenticationFrameworkRuntimeException { InboundAuthenticationRequestBuilder requestBuilder = getInboundRequestBuilder(request, response); if (requestBuilder == null) { throw new AuthenticationFrameworkRuntimeException( "No authentication request builder found to build the request"); } InboundAuthenticationRequest authenticationRequest = requestBuilder.buildRequest(request, response); if (request.getPathInfo().contains(InboundAuthenticationConstants.HTTP_PATH_PARAM_REQUEST)) { InboundAuthenticationResponse inboundAuthenticationResponse = doProcessRequest(request, response, authenticationRequest); if (inboundAuthenticationResponse.getStatusCode() == InboundAuthenticationConstants.StatusCode.REDIRECT) { try { sendRedirect(response, inboundAuthenticationResponse); } catch (IOException ex) { throw new AuthenticationFrameworkRuntimeException("Error occurred while redirecting response", ex); } } } else if (request.getPathInfo().contains(InboundAuthenticationConstants.HTTP_PATH_PARAM_RESPONSE)) { InboundAuthenticationResponse result = doProcessResponse(authenticationRequest); if (result.getRedirectURL() != null) { try { response.sendRedirect(result.getRedirectURL()); } catch (IOException ex) { throw new AuthenticationFrameworkRuntimeException( "Error occurred while redirecting response " + result.getRedirectURL(), ex); } } } } private void sendRedirect(HttpServletResponse response, InboundAuthenticationResponse inboundAuthenticationResponse) throws IOException { StringBuilder queryParams = new StringBuilder("?"); boolean isFirst = true; for (Map.Entry<String, String> entry : inboundAuthenticationResponse.getParameters().entrySet()) { if (isFirst) { queryParams.append(entry.getKey()); queryParams.append("="); queryParams.append(entry.getValue()); isFirst = false; } queryParams.append("&"); queryParams.append(entry.getKey()); queryParams.append("="); queryParams.append(entry.getValue()); } response.sendRedirect(inboundAuthenticationResponse.getRedirectURL() + queryParams); } /** * Process inbound request * * @param request Http request * @param response Http response * @param authenticationRequest Authentication request * @return Inbound authentication response * @throws AuthenticationFrameworkRuntimeException */ protected InboundAuthenticationResponse doProcessRequest(HttpServletRequest request, HttpServletResponse response, InboundAuthenticationRequest authenticationRequest) throws AuthenticationFrameworkRuntimeException { try { InboundAuthenticationResponse result = inboundAuthenticationManager.processRequest(authenticationRequest); return result; } catch (FrameworkException ex) { throw new AuthenticationFrameworkRuntimeException("Error occurred while processing authentication request", ex); } } /** * Process inbound authentication response * * @param authenticationRequest Authentication request * @return Inbound authentication response * @throws AuthenticationFrameworkRuntimeException */ protected InboundAuthenticationResponse doProcessResponse(InboundAuthenticationRequest authenticationRequest) throws AuthenticationFrameworkRuntimeException { try { String[] sessionDataKey = authenticationRequest.getParameters().get(FrameworkConstants.SESSION_DATA_KEY); if (!ArrayUtils.isEmpty(sessionDataKey) && !StringUtils.isEmpty(sessionDataKey[0])) { InboundAuthenticationContextCacheEntry cacheEntry = InboundAuthenticationUtil .getInboundAuthenticationContextToCache(sessionDataKey[0]); InboundAuthenticationResponse result = inboundAuthenticationManager.processResponse( cacheEntry.getInboundAuthenticationContext(), authenticationRequest); return result; } } catch (FrameworkException ex) { throw new AuthenticationFrameworkRuntimeException("Error occurred while processing authentication response", ex); } throw new AuthenticationFrameworkRuntimeException("No session found to process the response."); } }