package at.gv.egovernment.moa.id.auth.servlet; import java.util.Calendar; import org.apache.axis.AxisFault; import org.w3c.dom.Element; import org.w3c.dom.NodeList; 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.builder.SAMLResponseBuilder; 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$ * @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 = samlArtifactElem.getAttribute("RequestID"); String samlArtifact = DOMUtils.getText(samlArtifactElem); try { AuthenticationData authData = AuthenticationServer.getInstance(). getAuthenticationData(samlArtifact); // success samlAssertion = authData.getSamlAssertion(); statusCode = "samlp:Success"; statusMessageCode = "1200"; } 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.buildDateTime(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; } }