Ответ 1
Следующий рецепт работает для меня:
-
Получить токен SAMLResponse и декодировать его и раздуть:
// Base64 decode Base64 base64Decoder = new Base64(); byte[] xmlBytes = encodedXmlString.getBytes("UTF-8"); byte[] base64DecodedByteArray = base64Decoder.decode(xmlBytes); // Inflate (uncompress) the AuthnRequest data // First attempt to unzip the byte array according to DEFLATE (rfc 1951) Inflater inflater = new Inflater(true); inflater.setInput(base64DecodedByteArray); // since we are decompressing, it impossible to know how much space we // might need; hopefully this number is suitably big byte[] xmlMessageBytes = new byte[5000]; int resultLength = inflater.inflate(xmlMessageBytes); if (!inflater.finished()) { throw new RuntimeException("didn't allocate enough space to hold " + "decompressed data"); } inflater.end(); String decodedResponse = new String(xmlMessageBytes, 0, resultLength, "UTF-8"); return decodedResponse;
-
Разберите полученный XML. Здесь вы можете получить информацию, которая вам нужна, и, например, создать POJO с ней (это пример кода для разбора LogoutRequest, но будет аналогичен ответам):
// Parse the XML. SAX approach, we just need the ID attribute SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); // If we want to validate the doc we need to load the DTD // saxParserFactory.setValidating(true); // Get a SAXParser instance SAXParser saxParser = saxParserFactory.newSAXParser(); // Parse it XMLhandler xmLhandler = new XMLhandler(); saxParser.parse(new ByteArrayInputStream(xmlLogoutRequest.getBytes()), xmLhandler); // Return the SamlVO return xmLhandler.getSamlVO();
В моем случае использования я интересуюсь только несколькими элементами, поэтому я использую SAX:
public class XMLhandler extends DefaultHandler {
private SamlVO samlVO;
public XMLhandler() {
samlVO = new SamlVO();
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// Managing a LogoutRequest means that we are going to build a LogoutResponse
if (qName.equals("samlp:LogoutRequest")) {
// The ID value of a request will be the LogoutResponse InReponseTo attribute
samlVO.setInResponseTo(attributes.getValue("ID"));
// From the destination we can get the Issuer element
String destination = attributes.getValue("Destination");
if (destination != null) {
URL destinationUrl = null;
try {
destinationUrl = new URL(destination);
} catch (MalformedURLException e) {
// TODO: We could set the server hostname (take it from a property), but this URL SHOULD be well formed!
e.printStackTrace();
}
samlVO.setIssuer(destinationUrl.getHost());
}
}
}
public SamlVO getSamlVO() {
return samlVO;
}
}
Надеюсь, что это поможет,
Луис
PS: вы также можете использовать библиотеку, такую как OpenSAML
DefaultBootstrap.bootstrap();
HTTPRedirectDeflateDecoder decode = new HTTPRedirectDeflateDecoder(new BasicParserPool());
BasicSAMLMessageContext<LogoutRequest, ?, ?> messageContext = new BasicSAMLMessageContext<LogoutRequest, SAMLObject, SAMLObject>();
messageContext.setInboundMessageTransport(new HttpServletRequestAdapter(request));
decode.decode(messageContext);
XMLObjectBuilderFactory builderFactory = org.opensaml.Configuration.getBuilderFactory();
LogoutRequestBuilder logoutRequestBuilder = (LogoutRequestBuilder) builderFactory.getBuilder(LogoutRequest.DEFAULT_ELEMENT_NAME);
LogoutRequest logoutRequest = logoutRequestBuilder.buildObject();
logoutRequest = (LogoutRequest) messageContext.getInboundMessage();
Но будьте готовы включить в свой CLASSPATH несколько библиотек.