📄 samlsoapbinding.java
字号:
} catch (KeyManagementException ex) { throw new SAMLException("SAMLSOAPBinding.send() caught a key mgmt exception", ex); } catch (MalformedURLException ex) { throw new SAMLException("SAMLSOAPBinding.send() detected a malformed URL in the binding provided", ex); } catch (SAXException ex) { throw new SAMLException("SAMLSOAPBinding.send() caught an XML exception while parsing the response", ex); } catch (InvalidCanonicalizerException ex) { throw new SAMLException("SAMLSOAPBinding.send() caught a C14N exception while serializing the request", ex); } catch (CanonicalizationException ex) { throw new SAMLException("SAMLSOAPBinding.send() caught a C14N exception while serializing the request", ex); } catch (java.io.IOException ex) { throw new SAMLException("SAMLSOAPBinding.send() caught an I/O exception", ex); } finally { NDC.pop(); } } /** * Process the receipt of a SAML request<P> * * <B>NOTE to implementors:</B> If you want to talk to authorities that use * this implementation as their foundation, do not specify <I>xmlns:xsd</I> * or <I>xmlns:xsi</I> in your SOAP request, or if you do, specify the 2001 * schema namespaces. Any valid SOAP 1.1 envelope should validate, just * don't let your toolkit generate the schema prefixes. * * @param reqContext An instance of HttpServletRequest * @param requester The authenticated name of the requester, * determined from an SSL client certificate, or HTTP authentication * @return A SAML request * @exception SAMLException Base class of exceptions that may be thrown * during processing * @deprecated */ public SAMLRequest receive(Object reqContext, StringBuffer requester) throws SAMLException { // The client certificate chain should be accessible via an attribute. For now, // just pull out the common name from the subject of the first certificate. requester.setLength(0); HttpServletRequest req = (HttpServletRequest) reqContext; X509Certificate[] certarray = (X509Certificate[]) req.getAttribute("javax.servlet.request.X509Certificate"); if (certarray != null && certarray.length > 0) { StringTokenizer tokenizer = new StringTokenizer(certarray[0].getSubjectDN().getName(), ", "); while (tokenizer.hasMoreTokens()) { String token = tokenizer.nextToken(); if (token.startsWith("CN=")) { requester.append(token.substring(3)); break; } } log.debug("Requester name: " + requester); } else { log.debug("No Requester name available."); } return receive(reqContext); } /** * Process the receipt of a SAML request<P> * * <B>NOTE to implementors:</B> If you want to talk to authorities that use * this implementation as their foundation, do not specify <I>xmlns:xsd</I> * or <I>xmlns:xsi</I> in your SOAP request, or if you do, specify the 2001 * schema namespaces. Any valid SOAP 1.1 envelope should validate, just * don't let your toolkit generate the schema prefixes. * * @param reqContext An instance of HttpServletRequest * @return A SAML request * @exception SAMLException Base class of exceptions that may be thrown * during processing */ public SAMLRequest receive(Object reqContext) throws SAMLException { // This is a basic implementation that should suffice as a starting step // for any app-specific extensions, which should invoke super() and // then perform any additional checking. // The SAML SOAP binding requires that we receieve a SOAP envelope via // the POST method as text/xml. HttpServletRequest req = (HttpServletRequest)reqContext; if (!req.getMethod().equals("POST") || !req.getContentType().startsWith("text/xml")) throw new BindingException(SAMLException.REQUESTER, "SAMLSOAPBinding.receive() found a bad HTTP method or content type"); // The body of the POST contains the XML document to parse as a SOAP envelope. /* XXX - This is less than ideal because it assumes the envelope can be validated using the 2001/Schema namespace against the unofficial SOAP 1.1 schema. This isn't so terrible, except that if a SOAP toolkit used by a SHAR produces an envelope that explicitly sets the xsd or xsi namespaces to something older, we're screwed. (Apache SOAP parses without validating, so they can handle multiple schema levels.) */ try { Document doc = XML.parserPool.parse(req.getInputStream()); Element e = doc.getDocumentElement(); // The root must be a SOAP 1.1 envelope. if (!XML.isElementNamed(e,XML.SOAP11ENV_NS,"Envelope")) throw new SOAPException(SOAPException.VERSION, "SAMLSOAPBinding.receive() detected an incompatible or missing SOAP envelope"); /* Walk the children. If we encounter any headers with mustUnderstand, we have to bail. The thinking here is, we're not a "real" SOAP processor, but we have to emulate one that understands no headers. For now, assume we're the recipient. */ Node n = e.getFirstChild(); while (n != null && n.getNodeType() != Node.ELEMENT_NODE) n = n.getNextSibling(); if (XML.isElementNamed((Element)n,XML.SOAP11ENV_NS,"Header")) { Node header = n.getFirstChild(); while (header != null) { if (header.getNodeType() == Node.ELEMENT_NODE && ((Element)header).getAttributeNS(XML.SOAP11ENV_NS, "mustUnderstand").equals("1")) throw new SOAPException(SOAPException.MUSTUNDERSTAND, "SAMLSOAPBinding.receive() detected a mandatory SOAP header"); header = header.getNextSibling(); } // Advance to the Body element. n = n.getNextSibling(); while (n != null && n.getNodeType() != Node.ELEMENT_NODE) n = n.getNextSibling(); } /* The element after the optional Header is the mandatory Body (the meat). The SAML SOAP binding specifies the samlp:Request be immediately inside the body. Until we locate a Request (which we know validated), we're still in SOAP land. A SOAP envelope without a samlp:Request inside it is treated as a SOAP Client fault. */ if (n != null) { n = n.getFirstChild(); while (n != null && n.getNodeType() != Node.ELEMENT_NODE) n = n.getNextSibling(); } return new SAMLRequest((Element)n); } catch (SAXException e) { throw new SOAPException(SOAPException.CLIENT, "SAMLSOAPBinding.receive() detected an XML parsing error: " + e.getMessage()); } catch (java.io.IOException e) { throw new SOAPException(SOAPException.SERVER, "SAMLSOAPBinding.receive() detected an I/O error: " + e.getMessage()); } } /** 将SAMLResponse放入HttpServletResponse并返回至客户端 * Return a response to a requester * * @param respContext An instance of HttpServletResponse * @param response The SAML response to return (optional) * @param e An exception to translate into a SOAP fault * @exception java.io.IOException Thrown if sending of data fails */ public void respond(Object respContext, SAMLResponse response, SAMLException e) throws java.io.IOException { HttpServletResponse resp=(HttpServletResponse)respContext; try { Document doc = (e==null) ? response.toDOM().getOwnerDocument() : XML.parserPool.newDocument(); // Build the SOAP envelope and body for the response. Element env = doc.createElementNS(XML.SOAP11ENV_NS, "soap:Envelope"); env.setAttributeNS(XML.XMLNS_NS,"xmlns:soap", XML.SOAP11ENV_NS); env.setAttributeNS(XML.XMLNS_NS,"xmlns:xsd", XML.XSD_NS); env.setAttributeNS(XML.XMLNS_NS,"xmlns:xsi", XML.XSI_NS); if (doc.getDocumentElement()==null) doc.appendChild(env); else doc.replaceChild(env, doc.getDocumentElement()); Element body = doc.createElementNS(XML.SOAP11ENV_NS, "soap:Body"); env.appendChild(body); // If we're handed an exception, turn it into a SOAP fault. if (e != null) { Element fault = doc.createElementNS(XML.SOAP11ENV_NS, "soap:Fault"); body.appendChild(fault); Element elem = doc.createElementNS(null,"faultcode"); if (e instanceof SOAPException) { Iterator codes = e.getCodes(); if (codes.hasNext()) elem.appendChild(doc.createTextNode("soap:" + ((QName)codes.next()).getLocalName())); else elem.appendChild(doc.createTextNode("soap:" + SOAPException.SERVER.getLocalName())); } else elem.appendChild(doc.createTextNode("soap:" + SOAPException.SERVER.getLocalName())); fault.appendChild(elem); elem = doc.createElementNS(null,"faultstring"); fault.appendChild(elem).appendChild(doc.createTextNode(e.getMessage())); // The completed SOAP fault package constitutes the whole response. resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); Canonicalizer c = Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS); resp.getOutputStream().write(c.canonicalizeSubtree(env)); return; } // Attach the SAML response. body.appendChild(response.toDOM()); Canonicalizer c = Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS); resp.setContentType("text/xml; charset=UTF-8"); resp.getOutputStream().write(c.canonicalizeSubtree(env)); } catch (InvalidCanonicalizerException ex) { ex.printStackTrace(); resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "SAMLSOAPBinding.respond() unable to serialize XML document instance"); } catch (CanonicalizationException ex) { ex.printStackTrace(); resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "SAMLSOAPBinding.respond() unable to serialize XML document instance"); } catch (Exception ex) { ex.printStackTrace(); resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "SAMLSOAPBinding.respond() caught an unexpected exception: " + ex.getClass().getName() + " " + ex.getMessage()); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -