/******************************************************************************* * Copyright 2014 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.pvp2x.binding; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.opensaml.common.SAMLObject; import org.opensaml.common.binding.BasicSAMLMessageContext; import org.opensaml.common.binding.decoding.URIComparator; import org.opensaml.common.xml.SAMLConstants; import org.opensaml.saml2.binding.encoding.HTTPSOAP11Encoder; import org.opensaml.saml2.core.RequestAbstractType; import org.opensaml.saml2.core.StatusResponseType; import org.opensaml.saml2.metadata.SPSSODescriptor; import org.opensaml.saml2.metadata.provider.MetadataProvider; import org.opensaml.ws.message.decoder.MessageDecodingException; import org.opensaml.ws.message.encoder.MessageEncodingException; import org.opensaml.ws.soap.soap11.Envelope; import org.opensaml.ws.soap.soap11.decoder.http.HTTPSOAP11Decoder; import org.opensaml.ws.transport.http.HttpServletRequestAdapter; import org.opensaml.ws.transport.http.HttpServletResponseAdapter; import org.opensaml.xml.XMLObject; import org.opensaml.xml.parse.BasicParserPool; import org.opensaml.xml.security.SecurityException; import org.opensaml.xml.security.credential.Credential; import org.opensaml.xml.signature.SignableXMLObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import at.gv.egovernment.moa.id.commons.api.IRequest; import at.gv.egovernment.moa.id.protocols.pvp2x.PVP2XProtocol; import at.gv.egovernment.moa.id.protocols.pvp2x.config.MOADefaultBootstrap; import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.AttributQueryException; import at.gv.egovernment.moa.id.protocols.pvp2x.exceptions.PVP2Exception; import at.gv.egovernment.moa.id.protocols.pvp2x.messages.InboundMessageInterface; import at.gv.egovernment.moa.id.protocols.pvp2x.messages.MOARequest; import at.gv.egovernment.moa.id.protocols.pvp2x.metadata.MOAMetadataProvider; import at.gv.egovernment.moa.id.protocols.pvp2x.signer.IDPCredentialProvider; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.MiscUtil; @Service("PVPSOAPBinding") public class SoapBinding implements IDecoder, IEncoder { @Autowired(required=true) private MOAMetadataProvider metadataProvider; @Autowired private IDPCredentialProvider credentialProvider; public InboundMessageInterface decode(HttpServletRequest req, HttpServletResponse resp, MetadataProvider metadataProvider, boolean isSPEndPoint, URIComparator comparator) throws MessageDecodingException, SecurityException, PVP2Exception { HTTPSOAP11Decoder soapDecoder = new HTTPSOAP11Decoder(new BasicParserPool()); BasicSAMLMessageContext messageContext = new BasicSAMLMessageContext(); messageContext .setInboundMessageTransport(new HttpServletRequestAdapter( req)); messageContext.setMetadataProvider(metadataProvider); //TODO: update in a futher version: // requires a special SignedSOAPRequestPolicyRole because // messageContext.getInboundMessage() is not directly signed //set security context // BasicSecurityPolicy policy = new BasicSecurityPolicy(); // policy.getPolicyRules().add( // new MOAPVPSignedRequestPolicyRule( // TrustEngineFactory.getSignatureKnownKeysTrustEngine(), // SPSSODescriptor.DEFAULT_ELEMENT_NAME)); // SecurityPolicyResolver resolver = new StaticSecurityPolicyResolver( // policy); // messageContext.setSecurityPolicyResolver(resolver); //decode message soapDecoder.decode(messageContext); Envelope inboundMessage = (Envelope) messageContext .getInboundMessage(); if (inboundMessage.getBody() != null) { List xmlElemList = inboundMessage.getBody().getUnknownXMLObjects(); if (!xmlElemList.isEmpty()) { SignableXMLObject attrReq = (SignableXMLObject) xmlElemList.get(0); MOARequest request = new MOARequest(attrReq, getSAML2BindingName()); if (messageContext.getPeerEntityMetadata() != null) request.setEntityID(messageContext.getPeerEntityMetadata().getEntityID()); else if (attrReq instanceof RequestAbstractType) { RequestAbstractType attributeRequest = (RequestAbstractType) attrReq; try { if (MiscUtil.isNotEmpty(attributeRequest.getIssuer().getValue()) && metadataProvider.getRole( attributeRequest.getIssuer().getValue(), SPSSODescriptor.DEFAULT_ELEMENT_NAME) != null) request.setEntityID(attributeRequest.getIssuer().getValue()); } catch (Exception e) { Logger.warn("No Metadata found with EntityID " + attributeRequest.getIssuer().getValue()); } } request.setVerified(false); return request; } } Logger.error("Receive empty PVP 2.1 attributequery request."); throw new AttributQueryException("Receive empty PVP 2.1 attributequery request.", null); } public boolean handleDecode(String action, HttpServletRequest req) { return (req.getMethod().equals("POST") && (action.equals(PVP2XProtocol.SOAP) || action.equals(PVP2XProtocol.ATTRIBUTEQUERY))); } public void encodeRequest(HttpServletRequest req, HttpServletResponse resp, RequestAbstractType request, String targetLocation, String relayState, Credential credentials, IRequest pendingReq) throws MessageEncodingException, SecurityException, PVP2Exception { } public void encodeRespone(HttpServletRequest req, HttpServletResponse resp, StatusResponseType response, String targetLocation, String relayState, Credential credentials, IRequest pendingReq) throws MessageEncodingException, SecurityException, PVP2Exception { // try { // Credential credentials = credentialProvider // .getIDPAssertionSigningCredential(); //load default PVP security configurations MOADefaultBootstrap.initializeDefaultPVPConfiguration(); HTTPSOAP11Encoder encoder = new HTTPSOAP11Encoder(); HttpServletResponseAdapter responseAdapter = new HttpServletResponseAdapter( resp, true); BasicSAMLMessageContext context = new BasicSAMLMessageContext(); context.setOutboundSAMLMessageSigningCredential(credentials); context.setOutboundSAMLMessage(response); context.setOutboundMessageTransport(responseAdapter); encoder.encode(context); // } catch (CredentialsNotAvailableException e) { // e.printStackTrace(); // throw new SecurityException(e); // } } public String getSAML2BindingName() { return SAMLConstants.SAML2_SOAP11_BINDING_URI; } }