/*
* Copyright 2003 Federal Chancellery Austria
* MOA-ID has been developed in a cooperation between BRZ, the Federal
* Chancellery Austria - ICT staff unit, and Graz University of Technology.
*
* Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
* the European Commission - subsequent versions of the EUPL (the "Licence");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
* http://www.osor.eu/eupl/
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*
* This product combines work with different licenses. See the "NOTICE" text
* file for details on the various modules and licenses.
* The "NOTICE" text file is part of the distribution. Any derivative works
* that you distribute must include a readable copy of the "NOTICE" text file.
*/
package at.gv.egovernment.moa.id.auth.servlet;
import iaik.pki.PKIException;
import iaik.x509.X509Certificate;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Map;
import javax.net.ssl.SSLSocketFactory;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.transform.TransformerException;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.lang.StringEscapeUtils;
import org.w3c.dom.Element;
import at.gv.egovernment.moa.id.AuthenticationException;
import at.gv.egovernment.moa.id.MOAIDException;
import at.gv.egovernment.moa.id.auth.AuthenticationServer;
import at.gv.egovernment.moa.id.auth.MOAIDAuthConstants;
import at.gv.egovernment.moa.id.auth.WrongParametersException;
import at.gv.egovernment.moa.id.auth.builder.DataURLBuilder;
import at.gv.egovernment.moa.id.auth.data.AuthenticationSession;
import at.gv.egovernment.moa.id.config.ConnectionParameter;
import at.gv.egovernment.moa.id.config.auth.AuthConfigurationProvider;
import at.gv.egovernment.moa.id.config.auth.OAAuthParameter;
import at.gv.egovernment.moa.id.util.ParamValidatorUtils;
import at.gv.egovernment.moa.id.util.SSLUtils;
import at.gv.egovernment.moa.id.util.client.mis.simple.MISSessionId;
import at.gv.egovernment.moa.id.util.client.mis.simple.MISSimpleClient;
import at.gv.egovernment.moa.id.util.client.mis.simple.MISSimpleClientException;
import at.gv.egovernment.moa.logging.Logger;
import at.gv.egovernment.moa.util.DOMUtils;
import at.gv.egovernment.moa.util.URLEncoder;
/**
* Servlet requested for verifying the signed authentication block
* provided by the security layer implementation.
* Utilizes the {@link AuthenticationServer}.
*
* @author Paul Ivancsics
* @version $Id$
*/
public class VerifyAuthenticationBlockServlet extends AuthServlet {
/**
*
*/
private static final long serialVersionUID = -2409629495345900542L;
/**
* Constructor for VerifyAuthenticationBlockServlet.
*/
public VerifyAuthenticationBlockServlet() {
super();
}
/**
* GET requested by security layer implementation to verify
* that data URL resource is available.
* @see javax.servlet.http.HttpServlet#doGet(HttpServletRequest, HttpServletResponse)
*/
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//doPost(req, resp);
Logger.debug("GET VerifyAuthenticationBlock");
resp.setHeader(MOAIDAuthConstants.HEADER_EXPIRES,MOAIDAuthConstants.HEADER_VALUE_EXPIRES);
resp.setHeader(MOAIDAuthConstants.HEADER_PRAGMA,MOAIDAuthConstants.HEADER_VALUE_PRAGMA);
resp.setHeader(MOAIDAuthConstants.HEADER_CACHE_CONTROL,MOAIDAuthConstants.HEADER_VALUE_CACHE_CONTROL);
resp.addHeader(MOAIDAuthConstants.HEADER_CACHE_CONTROL,MOAIDAuthConstants.HEADER_VALUE_CACHE_CONTROL_IE);
}
/**
* Verifies the signed authentication block and redirects the browser
* to the online application requested, adding a parameter needed for
* retrieving the authentication data.
*
* Request parameters:
*
* - MOASessionID: ID of associated authentication session
* - XMLResponse:
<CreateXMLSignatureResponse>
*
* Response:
*
* - Status:
302
* - Header
"Location"
: URL of the online application requested, with
* parameters "Target"
(only if the online application is
* a public service) and "SAMLArtifact"
added
* - Error status:
500
*
* @see AuthenticationServer#verifyAuthenticationBlock
* @see javax.servlet.http.HttpServlet#doPost(HttpServletRequest, HttpServletResponse)
*/
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
Logger.debug("POST VerifyAuthenticationBlock");
resp.setHeader(MOAIDAuthConstants.HEADER_EXPIRES,MOAIDAuthConstants.HEADER_VALUE_EXPIRES);
resp.setHeader(MOAIDAuthConstants.HEADER_PRAGMA,MOAIDAuthConstants.HEADER_VALUE_PRAGMA);
resp.setHeader(MOAIDAuthConstants.HEADER_CACHE_CONTROL,MOAIDAuthConstants.HEADER_VALUE_CACHE_CONTROL);
resp.addHeader(MOAIDAuthConstants.HEADER_CACHE_CONTROL,MOAIDAuthConstants.HEADER_VALUE_CACHE_CONTROL_IE);
Map parameters;
try
{
parameters = getParameters(req);
} catch (FileUploadException e)
{
Logger.error("Parsing mulitpart/form-data request parameters failed: " + e.getMessage());
throw new IOException(e.getMessage());
}
String sessionID = req.getParameter(PARAM_SESSIONID);
String createXMLSignatureResponse = (String)parameters.get(PARAM_XMLRESPONSE);
// escape parameter strings
sessionID = StringEscapeUtils.escapeHtml(sessionID);
String redirectURL = null;
try {
// check parameter
if (!ParamValidatorUtils.isValidSessionID(sessionID))
throw new WrongParametersException("VerifyAuthenticationBlock", PARAM_SESSIONID, "auth.12");
if (!ParamValidatorUtils.isValidXMLDocument(createXMLSignatureResponse))
throw new WrongParametersException("VerifyAuthenticationBlock", PARAM_XMLRESPONSE, "auth.12");
AuthenticationSession session = AuthenticationServer.getSession(sessionID);
String samlArtifactBase64 =
AuthenticationServer.getInstance().verifyAuthenticationBlock(sessionID, createXMLSignatureResponse);
if (samlArtifactBase64 == null) {
//mandate Mode
AuthConfigurationProvider authConf= AuthConfigurationProvider.getInstance();
ConnectionParameter connectionParameters = authConf.getOnlineMandatesConnectionParameter();
SSLSocketFactory sslFactory = SSLUtils.getSSLSocketFactory(AuthConfigurationProvider.getInstance(), connectionParameters);
// get identitity link as byte[]
Element elem = session.getIdentityLink().getSamlAssertion();
String s = DOMUtils.serializeNode(elem);
//System.out.println("IDL: " + s);
byte[] idl = s.getBytes();
// redirect url
// build redirect(to the GetMISSessionIdSerlvet)
redirectURL =
new DataURLBuilder().buildDataURL(
session.getAuthURL(),
GET_MIS_SESSIONID,
session.getSessionID());
String oaURL = session.getOAURLRequested();
OAAuthParameter oaParam = authConf.getOnlineApplicationParameter(oaURL);
String profiles = oaParam.getMandateProfiles();
if (profiles == null) {
Logger.error("No Mandate/Profile for OA configured.");
throw new AuthenticationException("auth.16", new Object[] { GET_MIS_SESSIONID});
}
String profilesArray[] = profiles.split(",");
for(int i = 0; i < profilesArray.length; i++) {
profilesArray[i] = profilesArray[i].trim();
}
String oaFriendlyName = oaParam.getFriendlyName();
String mandateReferenceValue = session.getMandateReferenceValue();
X509Certificate cert = session.getSignerCertificate();
MISSessionId misSessionID = MISSimpleClient.sendSessionIdRequest(connectionParameters.getUrl(), idl, cert.getEncoded(), oaFriendlyName, redirectURL, mandateReferenceValue, profilesArray, sslFactory);
String redirectMISGUI = misSessionID.getRedirectURL();
if (misSessionID == null) {
Logger.error("Fehler bei Anfrage an Vollmachten Service. MIS Session ID ist null.");
throw new MISSimpleClientException("Fehler bei Anfrage an Vollmachten Service.");
}
session.setMISSessionID(misSessionID.getSessiondId());
resp.setStatus(302);
resp.addHeader("Location", redirectMISGUI);
Logger.debug("REDIRECT TO: " + redirectURL);
}
else {
if (!samlArtifactBase64.equals("Redirect to Input Processor")) {
redirectURL = session.getOAURLRequested();
if (!session.getBusinessService()) {
redirectURL = addURLParameter(redirectURL, PARAM_TARGET, URLEncoder.encode(session.getTarget(), "UTF-8"));
}
redirectURL = addURLParameter(redirectURL, PARAM_SAMLARTIFACT, URLEncoder.encode(samlArtifactBase64, "UTF-8"));
redirectURL = resp.encodeRedirectURL(redirectURL);
} else {
redirectURL = new DataURLBuilder().buildDataURL(session.getAuthURL(), AuthenticationServer.REQ_PROCESS_VALIDATOR_INPUT, session.getSessionID());
}
resp.setContentType("text/html");
resp.setStatus(302);
resp.addHeader("Location", redirectURL);
Logger.debug("REDIRECT TO: " + redirectURL);
}
}
catch (MOAIDException ex) {
handleError(null, ex, req, resp);
} catch (GeneralSecurityException e) {
handleError(null, e, req, resp);
} catch (PKIException e) {
handleError(null, e, req, resp);
} catch (MISSimpleClientException e) {
handleError(null, e, req, resp);
} catch (TransformerException e) {
handleError(null, e, req, resp);
}
}
/**
* Calls the MIS Service
* @param session
* @throws IOException
*/
// private void callMISService(AuthenticationSession session, HttpServletRequest req, HttpServletResponse resp) throws IOException {
//
// try {
// AuthConfigurationProvider authConf= AuthConfigurationProvider.getInstance();
// ConnectionParameter connectionParameters = authConf.getOnlineMandatesConnectionParameter();
// SSLSocketFactory sslFactory = SSLUtils.getSSLSocketFactory(AuthConfigurationProvider.getInstance(), connectionParameters);
//
// // get identitity link as byte[]
// Element elem = session.getIdentityLink().getSamlAssertion();
// String s = DOMUtils.serializeNode(elem);
//
// System.out.println("IDL: " + s);
//
// byte[] idl = s.getBytes();
//
// // redirect url
// // build redirect(to the GetMISSessionIdSerlvet)
// String redirectURL =
// new DataURLBuilder().buildDataURL(
// session.getAuthURL(),
// GET_MIS_SESSIONID,
// session.getSessionID());
//
// String oaURL = session.getOAURLRequested();
// OAAuthParameter oaParam = authConf.getOnlineApplicationParameter(oaURL);
// String profiles = oaParam.getMandateProfiles();
//
// if (profiles == null) {
// Logger.error("No Mandate/Profile for OA configured.");
// throw new AuthenticationException("auth.16", new Object[] { GET_MIS_SESSIONID});
// }
//
// String profilesArray[] = profiles.split(",");
// for(int i = 0; i < profilesArray.length; i++) {
// profilesArray[i] = profilesArray[i].trim();
// }
//
// String oaFriendlyName = oaParam.getFriendlyName();
// String mandateReferenceValue = session.getMandateReferenceValue();
// X509Certificate cert = session.getSignerCertificate();
// MISSessionId misSessionID = MISSimpleClient.sendSessionIdRequest(connectionParameters.getUrl(), idl, cert.getEncoded(), oaFriendlyName, redirectURL, mandateReferenceValue, profilesArray, sslFactory);
// String redirectMISGUI = misSessionID.getRedirectURL();
//
// if (misSessionID == null) {
// Logger.error("Fehler bei Anfrage an Vollmachten Service. MIS Session ID ist null.");
// throw new MISSimpleClientException("Fehler bei Anfrage an Vollmachten Service.");
// }
//
// session.setMISSessionID(misSessionID.getSessiondId());
//
// resp.setStatus(302);
// resp.addHeader("Location", redirectMISGUI);
// Logger.debug("REDIRECT TO: " + redirectURL);
// }
// catch (MOAIDException ex) {
// handleError(null, ex, req, resp);
// } catch (GeneralSecurityException ex) {
// handleError(null, ex, req, resp);
// } catch (PKIException e) {
// handleError(null, e, req, resp);
// } catch (MISSimpleClientException e) {
// handleError(null, e, req, resp);
// } catch (TransformerException e) {
// handleError(null, e, req, resp);
// }
// }
/**
* Adds a parameter to a URL.
* @param url the URL
* @param paramname parameter name
* @param paramvalue parameter value
* @return the URL with parameter added
*/
private static String addURLParameter(String url, String paramname, String paramvalue) {
String param = paramname + "=" + paramvalue;
if (url.indexOf("?") < 0)
return url + "?" + param;
else
return url + "&" + param;
}
}