/*
* 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.protocols.saml1;
import java.util.Calendar;
import org.apache.axis.AxisFault;
import org.apache.commons.lang3.StringEscapeUtils;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import at.gv.egovernment.moa.id.auth.builder.SAMLResponseBuilder;
import at.gv.egovernment.moa.id.auth.exception.AuthenticationException;
import at.gv.egovernment.moa.id.auth.exception.MOAIDException;
import at.gv.egovernment.moa.id.data.AuthenticationData;
import at.gv.egovernment.moa.id.util.MOAIDMessageProvider;
import at.gv.egovernment.moa.id.util.Random;
import at.gv.egovernment.moa.util.Constants;
import at.gv.egovernment.moa.util.DOMUtils;
import at.gv.egovernment.moa.util.DateTimeUtils;
import at.gv.egovernment.moa.util.XPathUtils;
/**
* Web service for picking up authentication data created in the MOA-ID Auth component.
*
* @author Paul Ivancsics
* @version $Id: GetAuthenticationDataService.java 1233 2012-01-26 21:59:33Z kstranacher $
* @see at.gv.egovernment.moa.id.auth.AuthenticationServer#getAuthenticationData
*/
public class GetAuthenticationDataService implements Constants {
/**
* Constructor for GetAuthenticationDataService.
*/
public GetAuthenticationDataService() {
super();
}
/**
* Takes a lt;samlp:Request>
containing a
* SAML artifact
and returns the corresponding
* authentication data lt;saml:Assertion>
* (obtained from the AuthenticationServer
),
* enclosed in a lt;samlp:Response>
.
*
Bad requests are mapped into various lt;samlp:StatusCode>
s,
* possibly containing enclosed sub-lt;samlp:StatusCode>
s.
* The status codes are defined in the SAML specification.
*
* @param requests request elements of type lt;samlp:Request>
;
* only 1 request element is allowed
* @return response element of type lt;samlp:Response>
,
* packed into an Element[]
* @throws AxisFault thrown when an error occurs in assembling the
* lt;samlp:Response>
*/
public Element[] Request(Element[] requests)
throws AxisFault {
Element request = requests[0];
Element[] responses = new Element[1];
String requestID = "";
String statusCode = "";
String subStatusCode = null;
String statusMessageCode = null;
String statusMessage = null;
String samlAssertion = "";
if (requests.length > 1) {
// more than 1 request given as parameter
statusCode = "samlp:Requester";
subStatusCode = "samlp:TooManyResponses";
statusMessageCode = "1201";
}
else {
try {
DOMUtils.validateElement(request, ALL_SCHEMA_LOCATIONS, null);
NodeList samlArtifactList = XPathUtils.selectNodeList(request, "samlp:AssertionArtifact");
if (samlArtifactList.getLength() == 0) {
// no SAML artifact given in request
statusCode = "samlp:Requester";
statusMessageCode = "1202";
}
else if (samlArtifactList.getLength() > 1) {
// too many SAML artifacts given in request
statusCode = "samlp:Requester";
subStatusCode = "samlp:TooManyResponses";
statusMessageCode = "1203";
}
else {
Element samlArtifactElem = (Element)samlArtifactList.item(0);
requestID = request.getAttribute("RequestID");
String samlArtifact = DOMUtils.getText(samlArtifactElem);
SAML1AuthenticationServer saml1server = SAML1AuthenticationServer.getInstace();
try {
AuthenticationData authData = saml1server.getSaml1AuthenticationData(samlArtifact);
// useUTC = authData.getUseUTC();
// success
samlAssertion = authData.getSamlAssertion();
statusCode = "samlp:Success";
statusMessageCode = "1200";
}
catch (ClassCastException ex) {
try {
Throwable error = saml1server.getErrorResponse(samlArtifact);
statusCode = "samlp:Responder";
subStatusCode = "samlp:RequestDenied";
if (error instanceof MOAIDException) {
statusMessageCode = ((MOAIDException)error).getMessageId();
statusMessage = StringEscapeUtils.escapeXml(((MOAIDException)error).getMessage());
} else {
statusMessage = StringEscapeUtils.escapeXml(error.getMessage());
}
} catch (Exception e) {
//no authentication data for given SAML artifact
statusCode = "samlp:Requester";
subStatusCode = "samlp:ResourceNotRecognized";
statusMessage = ex.toString();
}
}
catch (AuthenticationException ex) {
//no authentication data for given SAML artifact
statusCode = "samlp:Requester";
subStatusCode = "samlp:ResourceNotRecognized";
statusMessage = ex.toString();
}
}
}
catch (Throwable t) {
// invalid request format
statusCode = "samlp:Requester";
statusMessageCode = "1204";
}
}
try {
String responseID = Random.nextRandom();
String issueInstant = DateTimeUtils.buildDateTimeUTC(Calendar.getInstance());
if (statusMessage == null)
statusMessage = MOAIDMessageProvider.getInstance().getMessage(statusMessageCode, null);
responses[0] = new SAMLResponseBuilder().build(
responseID, requestID, issueInstant, statusCode, subStatusCode, statusMessage, samlAssertion);
}
catch (MOAIDException e) {
AxisFault fault = AxisFault.makeFault(e);
fault.setFaultDetail(new Element[] { e.toErrorResponse()});
throw fault;
}
catch (Throwable t) {
MOAIDException e = new MOAIDException("1299", null, t);
AxisFault fault = AxisFault.makeFault(e);
fault.setFaultDetail(new Element[] { e.toErrorResponse()});
throw fault;
}
return responses;
}
}