Untitled
unknown
plain_text
a year ago
7.2 kB
10
Indexable
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import java.io.StringWriter;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
public class SAMLDecoder {
public static class SAMLResponse {
private String issuer;
private String nameId;
private String recipient;
private Map<String, String> attributes;
public SAMLResponse() {
this.attributes = new HashMap<>();
}
// Getters and setters
public String getIssuer() { return issuer; }
public void setIssuer(String issuer) { this.issuer = issuer; }
public String getNameId() { return nameId; }
public void setNameId(String nameId) { this.nameId = nameId; }
public String getRecipient() { return recipient; }
public void setRecipient(String recipient) { this.recipient = recipient; }
public Map<String, String> getAttributes() { return attributes; }
}
public static SAMLResponse decodeSAMLResponseFromFile(File file) throws Exception {
SAMLResponse response = new SAMLResponse();
// Create a buffered reader with a large buffer size
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8),
8192 * 4)) { // 32KB buffer
// Read and decode the base64 content in chunks
StringBuilder base64Content = new StringBuilder();
char[] buffer = new char[8192]; // 8KB chunks
int bytesRead;
while ((bytesRead = reader.read(buffer)) != -1) {
base64Content.append(buffer, 0, bytesRead);
}
// Create decoder that can handle large content
Base64.Decoder decoder = Base64.getMimeDecoder();
byte[] decodedBytes = decoder.decode(base64Content.toString().replaceAll("\\s+", ""));
// Create XML input factory for streaming
XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
// Disable external entity processing
xmlInputFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
xmlInputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false);
// Create XML stream reader
XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(
new ByteArrayInputStream(decodedBytes));
// Process XML stream
String currentElement = "";
while (xmlStreamReader.hasNext()) {
int event = xmlStreamReader.next();
switch (event) {
case XMLStreamReader.START_ELEMENT:
currentElement = xmlStreamReader.getLocalName();
if ("Issuer".equals(currentElement)) {
response.setIssuer(xmlStreamReader.getElementText());
}
else if ("NameID".equals(currentElement)) {
response.setNameId(xmlStreamReader.getElementText());
}
else if ("SubjectConfirmationData".equals(currentElement)) {
response.setRecipient(xmlStreamReader.getAttributeValue(null, "Recipient"));
}
else if ("Attribute".equals(currentElement)) {
String attributeName = xmlStreamReader.getAttributeValue(null, "Name");
// Get the attribute value in the next iteration
while (xmlStreamReader.hasNext()) {
event = xmlStreamReader.next();
if (event == XMLStreamReader.START_ELEMENT &&
"AttributeValue".equals(xmlStreamReader.getLocalName())) {
String attributeValue = xmlStreamReader.getElementText();
response.getAttributes().put(attributeName, attributeValue);
break;
}
}
}
break;
}
}
xmlStreamReader.close();
}
return response;
}
public static void streamProcessLargeSAMLResponse(File inputFile, File outputFile) throws Exception {
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(new FileInputStream(inputFile), StandardCharsets.UTF_8),
8192 * 4)) {
// Process in chunks and write to output file
Base64.Decoder decoder = Base64.getMimeDecoder();
java.io.FileOutputStream fos = new java.io.FileOutputStream(outputFile);
char[] buffer = new char[8192];
int bytesRead;
byte[] decodedChunk;
while ((bytesRead = reader.read(buffer)) != -1) {
if (bytesRead > 0) {
String chunk = new String(buffer, 0, bytesRead);
// Remove whitespace and decode
decodedChunk = decoder.decode(chunk.replaceAll("\\s+", ""));
fos.write(decodedChunk);
}
}
fos.close();
}
}
// Example usage
public static void main(String[] args) {
try {
// For huge SAML response stored in a file
File inputFile = new File("huge_saml_response.txt");
// Option 1: Parse and get structured data
SAMLResponse response = decodeSAMLResponseFromFile(inputFile);
System.out.println("Issuer: " + response.getIssuer());
System.out.println("NameID: " + response.getNameId());
System.out.println("Recipient: " + response.getRecipient());
System.out.println("\nAttributes:");
response.getAttributes().forEach((key, value) ->
System.out.println(key + ": " + value));
// Option 2: Just decode to a new file
File outputFile = new File("decoded_saml.xml");
streamProcessLargeSAMLResponse(inputFile, outputFile);
} catch (Exception e) {
e.printStackTrace();
}
}
}Editor is loading...
Leave a Comment