keycloak-uncached

Merge pull request #3653 from hmlnarik/KEYCLOAK-3971-set-encoding-explicitly KEYCLOAK-3971

12/16/2016 11:39:57 AM

Changes

Details

diff --git a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/SamlUtil.java b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/SamlUtil.java
index e375e8c..b551707 100755
--- a/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/SamlUtil.java
+++ b/adapters/saml/core/src/main/java/org/keycloak/adapters/saml/SamlUtil.java
@@ -40,7 +40,7 @@ public class SamlUtil {
             httpFacade.getResponse().setHeader("Content-Type", "text/html");
             httpFacade.getResponse().setHeader("Pragma", "no-cache");
             httpFacade.getResponse().setHeader("Cache-Control", "no-cache, no-store");
-            httpFacade.getResponse().getOutputStream().write(html.getBytes());
+            httpFacade.getResponse().getOutputStream().write(html.getBytes(GeneralConstants.SAML_CHARSET));
             httpFacade.getResponse().end();
         } else {
             String uri = asRequest ? binding.redirectBinding(document).requestURI(actionUrl).toString() : binding.redirectBinding(document).responseURI(actionUrl).toString();
diff --git a/common/src/main/java/org/keycloak/common/util/StreamUtil.java b/common/src/main/java/org/keycloak/common/util/StreamUtil.java
index e1f87b9..72ff6df 100755
--- a/common/src/main/java/org/keycloak/common/util/StreamUtil.java
+++ b/common/src/main/java/org/keycloak/common/util/StreamUtil.java
@@ -21,6 +21,7 @@ import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.nio.charset.Charset;
 
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@@ -28,18 +29,41 @@ import java.io.InputStreamReader;
  */
 public final class StreamUtil {
 
+    private static final int BUFFER_LENGTH = 4096;
+
     private StreamUtil() {
     }
 
+    /**
+     * Reads string from byte input stream.
+     * @param in InputStream to build the String from
+     * @return String representation of the input stream contents decoded using default charset
+     * @throws IOException
+     * @deprecated Use {@link #readString(java.io.InputStream, java.nio.charset.Charset)} variant.
+     */
+    @Deprecated
     public static String readString(InputStream in) throws IOException
     {
-        char[] buffer = new char[1024];
+        return readString(in, Charset.defaultCharset());
+    }
+
+    /**
+     * Reads string from byte input stream.
+     * @param in InputStream to build the String from
+     * @param charset Charset used to decode the input stream
+     * @return String representation of the input stream contents decoded using given charset
+     * @throws IOException
+     * @deprecated Use {@link #readString(java.io.InputStream, java.nio.charset.Charset)} variant.
+     */
+    public static String readString(InputStream in, Charset charset) throws IOException
+    {
+        char[] buffer = new char[BUFFER_LENGTH];
         StringBuilder builder = new StringBuilder();
-        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+        BufferedReader reader = new BufferedReader(new InputStreamReader(in, charset));
         int wasRead;
         do
         {
-            wasRead = reader.read(buffer, 0, 1024);
+            wasRead = reader.read(buffer, 0, BUFFER_LENGTH);
             if (wasRead > 0)
             {
                 builder.append(buffer, 0, wasRead);
diff --git a/saml-core/src/main/java/org/keycloak/saml/BaseSAML2BindingBuilder.java b/saml-core/src/main/java/org/keycloak/saml/BaseSAML2BindingBuilder.java
index ca1f82e..86b3ecb 100755
--- a/saml-core/src/main/java/org/keycloak/saml/BaseSAML2BindingBuilder.java
+++ b/saml-core/src/main/java/org/keycloak/saml/BaseSAML2BindingBuilder.java
@@ -18,6 +18,7 @@
 package org.keycloak.saml;
 
 import org.jboss.logging.Logger;
+
 import org.keycloak.common.util.KeycloakUriBuilder;
 import org.keycloak.saml.common.constants.GeneralConstants;
 import org.keycloak.saml.common.constants.JBossSAMLConstants;
@@ -29,6 +30,7 @@ import org.keycloak.saml.processing.core.saml.v2.util.DocumentUtil;
 import org.keycloak.saml.processing.core.util.XMLEncryptionUtil;
 import org.keycloak.saml.processing.web.util.PostBindingUtil;
 import org.keycloak.saml.processing.web.util.RedirectBindingUtil;
+
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
@@ -38,7 +40,6 @@ import javax.crypto.spec.SecretKeySpec;
 import javax.xml.crypto.dsig.CanonicalizationMethod;
 import javax.xml.namespace.QName;
 import java.io.IOException;
-import java.io.UnsupportedEncodingException;
 import java.net.URI;
 import java.security.InvalidKeyException;
 import java.security.KeyPair;
@@ -155,8 +156,8 @@ public class BaseSAML2BindingBuilder<T extends BaseSAML2BindingBuilder> {
         }
 
         public String encoded() throws ProcessingException, ConfigurationException, IOException {
-            byte[] responseBytes = DocumentUtil.getDocumentAsString(document).getBytes("UTF-8");
-            return PostBindingUtil.base64Encode(new String(responseBytes));
+            byte[] responseBytes = DocumentUtil.getDocumentAsString(document).getBytes(GeneralConstants.SAML_CHARSET);
+            return PostBindingUtil.base64Encode(new String(responseBytes, GeneralConstants.SAML_CHARSET));
         }
         public Document getDocument() {
             return document;
@@ -300,8 +301,8 @@ public class BaseSAML2BindingBuilder<T extends BaseSAML2BindingBuilder> {
 
 
     public String buildHtmlPostResponse(Document responseDoc, String actionUrl, boolean asRequest) throws ProcessingException, ConfigurationException, IOException {
-        byte[] responseBytes = org.keycloak.saml.common.util.DocumentUtil.getDocumentAsString(responseDoc).getBytes("UTF-8");
-        String samlResponse = PostBindingUtil.base64Encode(new String(responseBytes));
+        byte[] responseBytes = org.keycloak.saml.common.util.DocumentUtil.getDocumentAsString(responseDoc).getBytes(GeneralConstants.SAML_CHARSET);
+        String samlResponse = PostBindingUtil.base64Encode(new String(responseBytes, GeneralConstants.SAML_CHARSET));
 
         return buildHtml(samlResponse, actionUrl, asRequest);
     }
@@ -315,26 +316,26 @@ public class BaseSAML2BindingBuilder<T extends BaseSAML2BindingBuilder> {
             key = GeneralConstants.SAML_REQUEST_KEY;
         }
 
-        builder.append("<HTML>");
-        builder.append("<HEAD>");
+        builder.append("<HTML>")
+          .append("<HEAD>")
 
-        builder.append("<TITLE>SAML HTTP Post Binding</TITLE>");
-        builder.append("</HEAD>");
-        builder.append("<BODY Onload=\"document.forms[0].submit()\">");
+          .append("<TITLE>SAML HTTP Post Binding</TITLE>")
+          .append("</HEAD>")
+          .append("<BODY Onload=\"document.forms[0].submit()\">")
 
-        builder.append("<FORM METHOD=\"POST\" ACTION=\"" + actionUrl + "\">");
-        builder.append("<INPUT TYPE=\"HIDDEN\" NAME=\"" + key + "\"" + " VALUE=\"" + samlResponse + "\"/>");
+          .append("<FORM METHOD=\"POST\" ACTION=\"").append(actionUrl).append("\">")
+          .append("<INPUT TYPE=\"HIDDEN\" NAME=\"").append(key).append("\"").append(" VALUE=\"").append(samlResponse).append("\"/>");
 
         if (isNotNull(relayState)) {
-            builder.append("<INPUT TYPE=\"HIDDEN\" NAME=\"RelayState\" " + "VALUE=\"" + escapeAttribute(relayState) + "\"/>");
+            builder.append("<INPUT TYPE=\"HIDDEN\" NAME=\"RelayState\" " + "VALUE=\"").append(escapeAttribute(relayState)).append("\"/>");
         }
 
-        builder.append("<NOSCRIPT>");
-        builder.append("<P>JavaScript is disabled. We strongly recommend to enable it. Click the button below to continue.</P>");
-        builder.append("<INPUT TYPE=\"SUBMIT\" VALUE=\"CONTINUE\" />");
-        builder.append("</NOSCRIPT>");
+        builder.append("<NOSCRIPT>")
+          .append("<P>JavaScript is disabled. We strongly recommend to enable it. Click the button below to continue.</P>")
+          .append("<INPUT TYPE=\"SUBMIT\" VALUE=\"CONTINUE\" />")
+          .append("</NOSCRIPT>")
 
-        builder.append("</FORM></BODY></HTML>");
+          .append("</FORM></BODY></HTML>");
 
         return builder.toString();
     }
@@ -342,7 +343,7 @@ public class BaseSAML2BindingBuilder<T extends BaseSAML2BindingBuilder> {
     public String base64Encoded(Document document) throws ConfigurationException, ProcessingException, IOException  {
         String documentAsString = DocumentUtil.getDocumentAsString(document);
         logger.debugv("saml document: {0}", documentAsString);
-        byte[] responseBytes = documentAsString.getBytes("UTF-8");
+        byte[] responseBytes = documentAsString.getBytes(GeneralConstants.SAML_CHARSET);
 
         return RedirectBindingUtil.deflateBase64URLEncode(responseBytes);
     }
@@ -364,9 +365,9 @@ public class BaseSAML2BindingBuilder<T extends BaseSAML2BindingBuilder> {
             byte[] sig = new byte[0];
             try {
                 signature.initSign(signingKeyPair.getPrivate());
-                signature.update(rawQuery.getBytes("UTF-8"));
+                signature.update(rawQuery.getBytes(GeneralConstants.SAML_CHARSET));
                 sig = signature.sign();
-            } catch (InvalidKeyException | UnsupportedEncodingException | SignatureException e) {
+            } catch (InvalidKeyException | SignatureException e) {
                 throw new ProcessingException(e);
             }
             String encodedSig = RedirectBindingUtil.base64URLEncode(sig);
diff --git a/saml-core/src/main/java/org/keycloak/saml/common/util/DocumentUtil.java b/saml-core/src/main/java/org/keycloak/saml/common/util/DocumentUtil.java
index b46220b..d9dd4e0 100755
--- a/saml-core/src/main/java/org/keycloak/saml/common/util/DocumentUtil.java
+++ b/saml-core/src/main/java/org/keycloak/saml/common/util/DocumentUtil.java
@@ -376,7 +376,7 @@ public class DocumentUtil {
             throw logger.processingError(e);
         }
 
-        return new String(baos.toByteArray());
+        return new String(baos.toByteArray(), GeneralConstants.SAML_CHARSET);
     }
 
     /**
diff --git a/saml-core/src/main/java/org/keycloak/saml/common/util/StaxUtil.java b/saml-core/src/main/java/org/keycloak/saml/common/util/StaxUtil.java
index 76ea66d..3c5cd38 100755
--- a/saml-core/src/main/java/org/keycloak/saml/common/util/StaxUtil.java
+++ b/saml-core/src/main/java/org/keycloak/saml/common/util/StaxUtil.java
@@ -75,7 +75,7 @@ public class StaxUtil {
     public static XMLEventWriter getXMLEventWriter(final OutputStream outStream) throws ProcessingException {
         XMLOutputFactory xmlOutputFactory = getXMLOutputFactory();
         try {
-            return xmlOutputFactory.createXMLEventWriter(outStream, "UTF-8");
+            return xmlOutputFactory.createXMLEventWriter(outStream, GeneralConstants.SAML_CHARSET_NAME);
         } catch (XMLStreamException e) {
             throw logger.processingError(e);
         }
@@ -93,7 +93,7 @@ public class StaxUtil {
     public static XMLStreamWriter getXMLStreamWriter(final OutputStream outStream) throws ProcessingException {
         XMLOutputFactory xmlOutputFactory = getXMLOutputFactory();
         try {
-            return xmlOutputFactory.createXMLStreamWriter(outStream, "UTF-8");
+            return xmlOutputFactory.createXMLStreamWriter(outStream, GeneralConstants.SAML_CHARSET_NAME);
         } catch (XMLStreamException e) {
             throw logger.processingError(e);
         }
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/api/saml/v2/request/SAML2Request.java b/saml-core/src/main/java/org/keycloak/saml/processing/api/saml/v2/request/SAML2Request.java
index 77c15ee..3b4b5db 100755
--- a/saml-core/src/main/java/org/keycloak/saml/processing/api/saml/v2/request/SAML2Request.java
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/api/saml/v2/request/SAML2Request.java
@@ -25,6 +25,7 @@ import org.keycloak.dom.saml.v2.protocol.RequestAbstractType;
 import org.keycloak.dom.saml.v2.protocol.ResponseType;
 import org.keycloak.saml.common.PicketLinkLogger;
 import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.common.constants.GeneralConstants;
 import org.keycloak.saml.common.constants.JBossSAMLConstants;
 import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
 import org.keycloak.saml.common.exceptions.ConfigurationException;
@@ -39,6 +40,7 @@ import org.keycloak.saml.processing.core.saml.v2.util.XMLTimeUtil;
 import org.keycloak.saml.processing.core.saml.v2.writers.SAMLRequestWriter;
 import org.keycloak.saml.processing.core.saml.v2.writers.SAMLResponseWriter;
 import org.keycloak.saml.processing.core.util.JAXPValidationUtil;
+
 import org.w3c.dom.Document;
 
 import javax.xml.datatype.XMLGregorianCalendar;
@@ -274,7 +276,7 @@ public class SAML2Request {
             writer.write((LogoutRequestType) rat);
         }
 
-        return DocumentUtil.getDocument(new String(bos.toByteArray()));
+        return DocumentUtil.getDocument(new String(bos.toByteArray(), GeneralConstants.SAML_CHARSET));
     }
 
     /**
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/api/util/DeflateUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/api/util/DeflateUtil.java
index f18656f..58923f8 100755
--- a/saml-core/src/main/java/org/keycloak/saml/processing/api/util/DeflateUtil.java
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/api/util/DeflateUtil.java
@@ -16,6 +16,8 @@
  */
 package org.keycloak.saml.processing.api.util;
 
+import org.keycloak.saml.common.constants.GeneralConstants;
+
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
@@ -62,7 +64,7 @@ public class DeflateUtil {
      * @throws IOException
      */
     public static byte[] encode(String message) throws IOException {
-        return encode(message.getBytes());
+        return encode(message.getBytes(GeneralConstants.SAML_CHARSET));
     }
 
     /**
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/metadata/SAMLEntityDescriptorParser.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/metadata/SAMLEntityDescriptorParser.java
index 6759583..2af29a3 100755
--- a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/metadata/SAMLEntityDescriptorParser.java
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/saml/metadata/SAMLEntityDescriptorParser.java
@@ -37,6 +37,7 @@ import org.keycloak.dom.saml.v2.metadata.SPSSODescriptorType;
 import org.keycloak.dom.xmlsec.w3.xmlenc.EncryptionMethodType;
 import org.keycloak.saml.common.PicketLinkLogger;
 import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.common.constants.GeneralConstants;
 import org.keycloak.saml.common.constants.JBossSAMLConstants;
 import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
 import org.keycloak.saml.common.exceptions.ParsingException;
@@ -44,6 +45,7 @@ import org.keycloak.saml.common.parsers.ParserNamespaceSupport;
 import org.keycloak.saml.common.util.StaxParserUtil;
 import org.keycloak.saml.processing.core.parsers.util.SAMLParserUtil;
 import org.keycloak.saml.processing.core.saml.v2.util.XMLTimeUtil;
+
 import org.w3c.dom.Element;
 
 import javax.xml.namespace.QName;
@@ -476,7 +478,7 @@ public class SAMLEntityDescriptorParser extends AbstractDescriptorParser impleme
                 keySize = BigInteger.valueOf(Long.valueOf(StaxParserUtil.getElementText(xmlEventReader)));
             } else if ("OAEPparams".equals(localPart)) {
                 startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
-                OAEPparams = StaxParserUtil.getElementText(xmlEventReader).getBytes();
+                OAEPparams = StaxParserUtil.getElementText(xmlEventReader).getBytes(GeneralConstants.SAML_CHARSET);
             } else {
                 throw logger.parserUnknownTag(localPart, startElement.getLocation());
             }
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/util/SAML11ParserUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/util/SAML11ParserUtil.java
index 1a5a204..1cbfa7a 100755
--- a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/util/SAML11ParserUtil.java
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/util/SAML11ParserUtil.java
@@ -41,6 +41,7 @@ import org.keycloak.dom.xmlsec.w3.xmldsig.X509CertificateType;
 import org.keycloak.dom.xmlsec.w3.xmldsig.X509DataType;
 import org.keycloak.saml.common.PicketLinkLogger;
 import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.common.constants.GeneralConstants;
 import org.keycloak.saml.common.constants.JBossSAMLConstants;
 import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
 import org.keycloak.saml.common.constants.WSTrustConstants;
@@ -50,6 +51,7 @@ import org.keycloak.saml.processing.core.parsers.saml.SAML11SubjectParser;
 import org.keycloak.saml.processing.core.saml.v1.SAML11Constants;
 import org.keycloak.saml.processing.core.saml.v2.util.SignatureUtil;
 import org.keycloak.saml.processing.core.saml.v2.util.XMLTimeUtil;
+
 import org.w3c.dom.Element;
 
 import javax.xml.namespace.QName;
@@ -561,7 +563,7 @@ public class SAML11ParserUtil {
 
                 X509CertificateType cert = new X509CertificateType();
                 String certValue = StaxParserUtil.getElementText(xmlEventReader);
-                cert.setEncodedCertificate(certValue.getBytes());
+                cert.setEncodedCertificate(certValue.getBytes(GeneralConstants.SAML_CHARSET));
                 x509.add(cert);
 
                 EndElement endElement = StaxParserUtil.getNextEndElement(xmlEventReader);
@@ -614,11 +616,11 @@ public class SAML11ParserUtil {
             if (tag.equals(WSTrustConstants.XMLDSig.MODULUS)) {
                 startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
                 String text = StaxParserUtil.getElementText(xmlEventReader);
-                rsaKeyValue.setModulus(text.getBytes());
+                rsaKeyValue.setModulus(text.getBytes(GeneralConstants.SAML_CHARSET));
             } else if (tag.equals(WSTrustConstants.XMLDSig.EXPONENT)) {
                 startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
                 String text = StaxParserUtil.getElementText(xmlEventReader);
-                rsaKeyValue.setExponent(text.getBytes());
+                rsaKeyValue.setExponent(text.getBytes(GeneralConstants.SAML_CHARSET));
             } else
                 throw logger.parserUnknownTag(tag, startElement.getLocation());
         }
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/util/SAMLParserUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/util/SAMLParserUtil.java
index c2337b2..b1ed278 100755
--- a/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/util/SAMLParserUtil.java
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/parsers/util/SAMLParserUtil.java
@@ -34,6 +34,7 @@ import org.keycloak.dom.xmlsec.w3.xmldsig.X509CertificateType;
 import org.keycloak.dom.xmlsec.w3.xmldsig.X509DataType;
 import org.keycloak.saml.common.PicketLinkLogger;
 import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.common.constants.GeneralConstants;
 import org.keycloak.saml.common.constants.JBossSAMLConstants;
 import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
 import org.keycloak.saml.common.constants.WSTrustConstants;
@@ -42,6 +43,7 @@ import org.keycloak.saml.common.util.StaxParserUtil;
 import org.keycloak.saml.common.util.StringUtil;
 import org.keycloak.saml.processing.core.saml.v2.util.SignatureUtil;
 import org.keycloak.saml.processing.core.saml.v2.util.XMLTimeUtil;
+
 import org.w3c.dom.Element;
 
 import javax.xml.datatype.XMLGregorianCalendar;
@@ -98,7 +100,7 @@ public class SAMLParserUtil {
 
                 X509CertificateType cert = new X509CertificateType();
                 String certValue = StaxParserUtil.getElementText(xmlEventReader);
-                cert.setEncodedCertificate(certValue.getBytes());
+                cert.setEncodedCertificate(certValue.getBytes(GeneralConstants.SAML_CHARSET));
                 x509.add(cert);
 
                 EndElement endElement = StaxParserUtil.getNextEndElement(xmlEventReader);
@@ -151,11 +153,11 @@ public class SAMLParserUtil {
             if (tag.equals(WSTrustConstants.XMLDSig.MODULUS)) {
                 startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
                 String text = StaxParserUtil.getElementText(xmlEventReader);
-                rsaKeyValue.setModulus(text.getBytes());
+                rsaKeyValue.setModulus(text.getBytes(GeneralConstants.SAML_CHARSET));
             } else if (tag.equals(WSTrustConstants.XMLDSig.EXPONENT)) {
                 startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
                 String text = StaxParserUtil.getElementText(xmlEventReader);
-                rsaKeyValue.setExponent(text.getBytes());
+                rsaKeyValue.setExponent(text.getBytes(GeneralConstants.SAML_CHARSET));
             } else
                 throw logger.parserUnknownTag(tag, startElement.getLocation());
         }
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/AssertionUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/AssertionUtil.java
index ed941a0..89d6680 100755
--- a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/AssertionUtil.java
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/AssertionUtil.java
@@ -49,6 +49,7 @@ import org.keycloak.saml.processing.core.parsers.saml.SAMLParser;
 import org.keycloak.saml.processing.core.saml.v2.writers.SAMLAssertionWriter;
 import org.keycloak.saml.processing.core.util.JAXPValidationUtil;
 import org.keycloak.saml.processing.core.util.XMLEncryptionUtil;
+
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
@@ -62,7 +63,9 @@ import java.security.PublicKey;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
+
 import org.keycloak.rotation.HardcodedKeyLocator;
+import org.keycloak.saml.common.constants.GeneralConstants;
 
 /**
  * Utility to deal with assertions
@@ -87,7 +90,7 @@ public class AssertionUtil {
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         SAMLAssertionWriter writer = new SAMLAssertionWriter(StaxUtil.getXMLStreamWriter(baos));
         writer.write(assertion);
-        return new String(baos.toByteArray());
+        return new String(baos.toByteArray(), GeneralConstants.SAML_CHARSET);
     }
 
     /**
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/SignatureUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/SignatureUtil.java
index 352144d..1ba4d74 100755
--- a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/SignatureUtil.java
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/SignatureUtil.java
@@ -22,11 +22,13 @@ import org.keycloak.dom.xmlsec.w3.xmldsig.RSAKeyValueType;
 import org.keycloak.dom.xmlsec.w3.xmldsig.SignatureType;
 import org.keycloak.saml.common.PicketLinkLogger;
 import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.common.constants.GeneralConstants;
 import org.keycloak.saml.common.constants.JBossSAMLConstants;
 import org.keycloak.saml.common.constants.WSTrustConstants;
 import org.keycloak.saml.common.exceptions.ParsingException;
 import org.keycloak.saml.common.util.Base64;
 import org.keycloak.saml.processing.core.constants.PicketLinkFederationConstants;
+
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
@@ -106,7 +108,7 @@ public class SignatureUtil {
         String algo = signingKey.getAlgorithm();
         Signature sig = getSignature(algo);
         sig.initSign(signingKey);
-        sig.update(stringToBeSigned.getBytes());
+        sig.update(stringToBeSigned.getBytes(GeneralConstants.SAML_CHARSET));
         return sig.sign();
     }
 
@@ -191,7 +193,7 @@ public class SignatureUtil {
                 Element childElement = (Element) node;
                 String tag = childElement.getLocalName();
 
-                byte[] text = childElement.getTextContent().getBytes();
+                byte[] text = childElement.getTextContent().getBytes(GeneralConstants.SAML_CHARSET);
 
                 if (WSTrustConstants.XMLDSig.P.equals(tag)) {
                     dsa.setP(text);
@@ -232,7 +234,7 @@ public class SignatureUtil {
                 Element childElement = (Element) node;
                 String tag = childElement.getLocalName();
 
-                byte[] text = childElement.getTextContent().getBytes();
+                byte[] text = childElement.getTextContent().getBytes(GeneralConstants.SAML_CHARSET);
 
                 if (WSTrustConstants.XMLDSig.MODULUS.equals(tag)) {
                     rsa.setModulus(text);
@@ -262,8 +264,8 @@ public class SignatureUtil {
             byte[] exponent = pubKey.getPublicExponent().toByteArray();
 
             RSAKeyValueType rsaKeyValue = new RSAKeyValueType();
-            rsaKeyValue.setModulus(Base64.encodeBytes(modulus).getBytes());
-            rsaKeyValue.setExponent(Base64.encodeBytes(exponent).getBytes());
+            rsaKeyValue.setModulus(Base64.encodeBytes(modulus).getBytes(GeneralConstants.SAML_CHARSET));
+            rsaKeyValue.setExponent(Base64.encodeBytes(exponent).getBytes(GeneralConstants.SAML_CHARSET));
             return rsaKeyValue;
         } else if (key instanceof DSAPublicKey) {
             DSAPublicKey pubKey = (DSAPublicKey) key;
@@ -273,10 +275,10 @@ public class SignatureUtil {
             byte[] Y = pubKey.getY().toByteArray();
 
             DSAKeyValueType dsaKeyValue = new DSAKeyValueType();
-            dsaKeyValue.setP(Base64.encodeBytes(P).getBytes());
-            dsaKeyValue.setQ(Base64.encodeBytes(Q).getBytes());
-            dsaKeyValue.setG(Base64.encodeBytes(G).getBytes());
-            dsaKeyValue.setY(Base64.encodeBytes(Y).getBytes());
+            dsaKeyValue.setP(Base64.encodeBytes(P).getBytes(GeneralConstants.SAML_CHARSET));
+            dsaKeyValue.setQ(Base64.encodeBytes(Q).getBytes(GeneralConstants.SAML_CHARSET));
+            dsaKeyValue.setG(Base64.encodeBytes(G).getBytes(GeneralConstants.SAML_CHARSET));
+            dsaKeyValue.setY(Base64.encodeBytes(Y).getBytes(GeneralConstants.SAML_CHARSET));
             return dsaKeyValue;
         }
         throw logger.unsupportedType(key.toString());
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/StaxWriterUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/StaxWriterUtil.java
index 5c83183..3473743 100755
--- a/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/StaxWriterUtil.java
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/saml/v2/util/StaxWriterUtil.java
@@ -27,9 +27,11 @@ import org.keycloak.dom.xmlsec.w3.xmldsig.X509DataType;
 import org.keycloak.saml.common.ErrorCodes;
 import org.keycloak.saml.common.PicketLinkLogger;
 import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.common.constants.GeneralConstants;
 import org.keycloak.saml.common.constants.WSTrustConstants;
 import org.keycloak.saml.common.exceptions.ProcessingException;
 import org.keycloak.saml.common.util.StaxUtil;
+
 import org.w3c.dom.Element;
 
 import javax.xml.stream.XMLStreamWriter;
@@ -77,7 +79,7 @@ public class StaxWriterUtil {
                 X509CertificateType cert = (X509CertificateType) obj;
                 StaxUtil.writeStartElement(writer, WSTrustConstants.XMLDSig.DSIG_PREFIX, WSTrustConstants.XMLDSig.X509CERT,
                         WSTrustConstants.XMLDSig.DSIG_NS);
-                StaxUtil.writeCharacters(writer, new String(cert.getEncodedCertificate()));
+                StaxUtil.writeCharacters(writer, new String(cert.getEncodedCertificate(), GeneralConstants.SAML_CHARSET));
                 StaxUtil.writeEndElement(writer);
             }
             StaxUtil.writeEndElement(writer);
@@ -105,13 +107,13 @@ public class StaxWriterUtil {
         // write the rsa key modulus.
         byte[] modulus = type.getModulus();
         StaxUtil.writeStartElement(writer, prefix, WSTrustConstants.XMLDSig.MODULUS, WSTrustConstants.DSIG_NS);
-        StaxUtil.writeCharacters(writer, new String(modulus));
+        StaxUtil.writeCharacters(writer, new String(modulus, GeneralConstants.SAML_CHARSET));
         StaxUtil.writeEndElement(writer);
 
         // write the rsa key exponent.
         byte[] exponent = type.getExponent();
         StaxUtil.writeStartElement(writer, prefix, WSTrustConstants.XMLDSig.EXPONENT, WSTrustConstants.DSIG_NS);
-        StaxUtil.writeCharacters(writer, new String(exponent));
+        StaxUtil.writeCharacters(writer, new String(exponent, GeneralConstants.SAML_CHARSET));
         StaxUtil.writeEndElement(writer);
 
         StaxUtil.writeEndElement(writer);
@@ -126,37 +128,37 @@ public class StaxWriterUtil {
         byte[] p = type.getP();
         if (p != null) {
             StaxUtil.writeStartElement(writer, prefix, WSTrustConstants.XMLDSig.P, WSTrustConstants.DSIG_NS);
-            StaxUtil.writeCharacters(writer, new String(p));
+            StaxUtil.writeCharacters(writer, new String(p, GeneralConstants.SAML_CHARSET));
             StaxUtil.writeEndElement(writer);
         }
         byte[] q = type.getQ();
         if (q != null) {
             StaxUtil.writeStartElement(writer, prefix, WSTrustConstants.XMLDSig.Q, WSTrustConstants.DSIG_NS);
-            StaxUtil.writeCharacters(writer, new String(q));
+            StaxUtil.writeCharacters(writer, new String(q, GeneralConstants.SAML_CHARSET));
             StaxUtil.writeEndElement(writer);
         }
         byte[] g = type.getG();
         if (g != null) {
             StaxUtil.writeStartElement(writer, prefix, WSTrustConstants.XMLDSig.G, WSTrustConstants.DSIG_NS);
-            StaxUtil.writeCharacters(writer, new String(g));
+            StaxUtil.writeCharacters(writer, new String(g, GeneralConstants.SAML_CHARSET));
             StaxUtil.writeEndElement(writer);
         }
         byte[] y = type.getY();
         if (y != null) {
             StaxUtil.writeStartElement(writer, prefix, WSTrustConstants.XMLDSig.Y, WSTrustConstants.DSIG_NS);
-            StaxUtil.writeCharacters(writer, new String(y));
+            StaxUtil.writeCharacters(writer, new String(y, GeneralConstants.SAML_CHARSET));
             StaxUtil.writeEndElement(writer);
         }
         byte[] seed = type.getSeed();
         if (seed != null) {
             StaxUtil.writeStartElement(writer, prefix, WSTrustConstants.XMLDSig.SEED, WSTrustConstants.DSIG_NS);
-            StaxUtil.writeCharacters(writer, new String(seed));
+            StaxUtil.writeCharacters(writer, new String(seed, GeneralConstants.SAML_CHARSET));
             StaxUtil.writeEndElement(writer);
         }
         byte[] pgen = type.getPgenCounter();
         if (pgen != null) {
             StaxUtil.writeStartElement(writer, prefix, WSTrustConstants.XMLDSig.PGEN_COUNTER, WSTrustConstants.DSIG_NS);
-            StaxUtil.writeCharacters(writer, new String(pgen));
+            StaxUtil.writeCharacters(writer, new String(pgen, GeneralConstants.SAML_CHARSET));
             StaxUtil.writeEndElement(writer);
         }
 
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/util/JAXBUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/JAXBUtil.java
index c7b3b79..be255e2 100755
--- a/saml-core/src/main/java/org/keycloak/saml/processing/core/util/JAXBUtil.java
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/JAXBUtil.java
@@ -18,6 +18,8 @@ package org.keycloak.saml.processing.core.util;
 
 import org.keycloak.saml.common.PicketLinkLogger;
 import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.common.constants.GeneralConstants;
+
 import org.xml.sax.ErrorHandler;
 import org.xml.sax.SAXException;
 import org.xml.sax.SAXParseException;
@@ -89,7 +91,7 @@ public class JAXBUtil {
 
         JAXBContext jc = getJAXBContext(pkgName);
         Marshaller marshaller = jc.createMarshaller();
-        marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
+        marshaller.setProperty(Marshaller.JAXB_ENCODING, GeneralConstants.SAML_CHARSET_NAME);
         marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.FALSE); // Breaks signatures
         return marshaller;
     }
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/core/util/XMLSignatureUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/XMLSignatureUtil.java
index 6ad6513..53228c9 100755
--- a/saml-core/src/main/java/org/keycloak/saml/processing/core/util/XMLSignatureUtil.java
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/core/util/XMLSignatureUtil.java
@@ -22,6 +22,7 @@ import org.keycloak.dom.xmlsec.w3.xmldsig.RSAKeyValueType;
 import org.keycloak.dom.xmlsec.w3.xmldsig.SignatureType;
 import org.keycloak.saml.common.PicketLinkLogger;
 import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.common.constants.GeneralConstants;
 import org.keycloak.saml.common.constants.JBossSAMLConstants;
 import org.keycloak.saml.common.constants.WSTrustConstants;
 import org.keycloak.saml.common.exceptions.ParsingException;
@@ -572,7 +573,7 @@ public class XMLSignatureUtil {
 
         try {
             CertificateFactory cf = CertificateFactory.getInstance("X.509");
-            ByteArrayInputStream bais = new ByteArrayInputStream(derFormattedString.getBytes());
+            ByteArrayInputStream bais = new ByteArrayInputStream(derFormattedString.getBytes(GeneralConstants.SAML_CHARSET));
 
             while (bais.available() > 0) {
                 cert = (X509Certificate) cf.generateCertificate(bais);
@@ -603,7 +604,7 @@ public class XMLSignatureUtil {
                 Element childElement = (Element) node;
                 String tag = childElement.getLocalName();
 
-                byte[] text = childElement.getTextContent().getBytes();
+                byte[] text = childElement.getTextContent().getBytes(GeneralConstants.SAML_CHARSET);
 
                 if (WSTrustConstants.XMLDSig.P.equals(tag)) {
                     dsa.setP(text);
@@ -644,7 +645,7 @@ public class XMLSignatureUtil {
                 Element childElement = (Element) node;
                 String tag = childElement.getLocalName();
 
-                byte[] text = childElement.getTextContent().getBytes();
+                byte[] text = childElement.getTextContent().getBytes(GeneralConstants.SAML_CHARSET);
 
                 if (WSTrustConstants.XMLDSig.MODULUS.equals(tag)) {
                     rsa.setModulus(text);
@@ -674,8 +675,8 @@ public class XMLSignatureUtil {
             byte[] exponent = pubKey.getPublicExponent().toByteArray();
 
             RSAKeyValueType rsaKeyValue = new RSAKeyValueType();
-            rsaKeyValue.setModulus(Base64.encodeBytes(modulus).getBytes());
-            rsaKeyValue.setExponent(Base64.encodeBytes(exponent).getBytes());
+            rsaKeyValue.setModulus(Base64.encodeBytes(modulus).getBytes(GeneralConstants.SAML_CHARSET));
+            rsaKeyValue.setExponent(Base64.encodeBytes(exponent).getBytes(GeneralConstants.SAML_CHARSET));
             return rsaKeyValue;
         } else if (key instanceof DSAPublicKey) {
             DSAPublicKey pubKey = (DSAPublicKey) key;
@@ -685,10 +686,10 @@ public class XMLSignatureUtil {
             byte[] Y = pubKey.getY().toByteArray();
 
             DSAKeyValueType dsaKeyValue = new DSAKeyValueType();
-            dsaKeyValue.setP(Base64.encodeBytes(P).getBytes());
-            dsaKeyValue.setQ(Base64.encodeBytes(Q).getBytes());
-            dsaKeyValue.setG(Base64.encodeBytes(G).getBytes());
-            dsaKeyValue.setY(Base64.encodeBytes(Y).getBytes());
+            dsaKeyValue.setP(Base64.encodeBytes(P).getBytes(GeneralConstants.SAML_CHARSET));
+            dsaKeyValue.setQ(Base64.encodeBytes(Q).getBytes(GeneralConstants.SAML_CHARSET));
+            dsaKeyValue.setG(Base64.encodeBytes(G).getBytes(GeneralConstants.SAML_CHARSET));
+            dsaKeyValue.setY(Base64.encodeBytes(Y).getBytes(GeneralConstants.SAML_CHARSET));
             return dsaKeyValue;
         }
         throw logger.unsupportedType(key.toString());
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/web/util/PostBindingUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/web/util/PostBindingUtil.java
index eaf338a..57c5191 100755
--- a/saml-core/src/main/java/org/keycloak/saml/processing/web/util/PostBindingUtil.java
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/web/util/PostBindingUtil.java
@@ -18,6 +18,7 @@ package org.keycloak.saml.processing.web.util;
 
 import org.keycloak.saml.common.PicketLinkLogger;
 import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.common.constants.GeneralConstants;
 import org.keycloak.saml.common.util.Base64;
 
 import java.io.ByteArrayInputStream;
@@ -42,7 +43,7 @@ public class PostBindingUtil {
      * @return
      */
     public static String base64Encode(String stringToEncode) throws IOException {
-        return Base64.encodeBytes(stringToEncode.getBytes("UTF-8"), Base64.DONT_BREAK_LINES);
+        return Base64.encodeBytes(stringToEncode.getBytes(GeneralConstants.SAML_CHARSET), Base64.DONT_BREAK_LINES);
     }
 
     /**
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/web/util/RedirectBindingSignatureUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/web/util/RedirectBindingSignatureUtil.java
index c559f2b..1e2087a 100755
--- a/saml-core/src/main/java/org/keycloak/saml/processing/web/util/RedirectBindingSignatureUtil.java
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/web/util/RedirectBindingSignatureUtil.java
@@ -79,7 +79,7 @@ public class RedirectBindingSignatureUtil {
         String urlEncodedRelayState = null;
 
         if (isNotNull(relayState))
-            urlEncodedRelayState = URLEncoder.encode(relayState, "UTF-8");
+            urlEncodedRelayState = URLEncoder.encode(relayState, GeneralConstants.SAML_CHARSET_NAME);
 
         byte[] sigValue = computeSignature(GeneralConstants.SAML_REQUEST_KEY, urlEncodedRequest, urlEncodedRelayState,
                 signingKey);
@@ -113,7 +113,7 @@ public class RedirectBindingSignatureUtil {
 
         String urlEncodedRelayState = null;
         if (isNotNull(relayState))
-            urlEncodedRelayState = URLEncoder.encode(relayState, "UTF-8");
+            urlEncodedRelayState = URLEncoder.encode(relayState, GeneralConstants.SAML_CHARSET_NAME);
 
         byte[] sigValue = computeSignature(GeneralConstants.SAML_RESPONSE_KEY, urlEncodedResponse, urlEncodedRelayState,
                 signingKey);
@@ -234,7 +234,7 @@ public class RedirectBindingSignatureUtil {
         addParameter(sb, GeneralConstants.SAML_SIG_ALG_REQUEST_KEY,
                 RedirectBindingSignatureUtil.getTokenValue(queryString, GeneralConstants.SAML_SIG_ALG_REQUEST_KEY));
 
-        return SignatureUtil.validate(sb.toString().getBytes("UTF-8"), sigValue, validatingKey);
+        return SignatureUtil.validate(sb.toString().getBytes(GeneralConstants.SAML_CHARSET), sigValue, validatingKey);
     }
 
     private static boolean isRequestQueryString(String queryString) {
@@ -257,7 +257,7 @@ public class RedirectBindingSignatureUtil {
         String algo = signingKey.getAlgorithm();
         String sigAlg = SignatureUtil.getXMLSignatureAlgorithmURI(algo);
 
-        sigAlg = URLEncoder.encode(sigAlg, "UTF-8");
+        sigAlg = URLEncoder.encode(sigAlg, GeneralConstants.SAML_CHARSET_NAME);
 
         addParameter(sb, GeneralConstants.SAML_SIG_ALG_REQUEST_KEY, sigAlg);
 
@@ -291,7 +291,7 @@ public class RedirectBindingSignatureUtil {
         // SigAlg
         String sigAlg = SignatureUtil.getXMLSignatureAlgorithmURI(sigAlgo);
 
-        sigAlg = URLEncoder.encode(sigAlg, "UTF-8");
+        sigAlg = URLEncoder.encode(sigAlg, GeneralConstants.SAML_CHARSET_NAME);
 
         addParameter(sb, GeneralConstants.SAML_SIG_ALG_REQUEST_KEY, sigAlg);
 
diff --git a/saml-core/src/main/java/org/keycloak/saml/processing/web/util/RedirectBindingUtil.java b/saml-core/src/main/java/org/keycloak/saml/processing/web/util/RedirectBindingUtil.java
index 7b22767..587113c 100755
--- a/saml-core/src/main/java/org/keycloak/saml/processing/web/util/RedirectBindingUtil.java
+++ b/saml-core/src/main/java/org/keycloak/saml/processing/web/util/RedirectBindingUtil.java
@@ -16,6 +16,7 @@
  */
 package org.keycloak.saml.processing.web.util;
 
+import org.keycloak.saml.common.constants.GeneralConstants;
 import org.keycloak.saml.common.util.Base64;
 import org.keycloak.saml.common.util.StringUtil;
 import org.keycloak.saml.processing.api.util.DeflateUtil;
@@ -43,7 +44,7 @@ public class RedirectBindingUtil {
      * @throws IOException
      */
     public static String urlEncode(String str) throws IOException {
-        return URLEncoder.encode(str, "UTF-8");
+        return URLEncoder.encode(str, GeneralConstants.SAML_CHARSET_NAME);
     }
 
     /**
@@ -56,7 +57,7 @@ public class RedirectBindingUtil {
      * @throws IOException
      */
     public static String urlDecode(String str) throws IOException {
-        return URLDecoder.decode(str, "UTF-8");
+        return URLDecoder.decode(str, GeneralConstants.SAML_CHARSET_NAME);
     }
 
     /**
@@ -97,7 +98,7 @@ public class RedirectBindingUtil {
      * @throws IOException
      */
     public static String deflateBase64URLEncode(String stringToEncode) throws IOException {
-        return deflateBase64URLEncode(stringToEncode.getBytes("UTF-8"));
+        return deflateBase64URLEncode(stringToEncode.getBytes(GeneralConstants.SAML_CHARSET));
     }
 
     /**
diff --git a/saml-core/src/main/java/org/keycloak/saml/SAMLRequestParser.java b/saml-core/src/main/java/org/keycloak/saml/SAMLRequestParser.java
index 5f1257b..00160e6 100755
--- a/saml-core/src/main/java/org/keycloak/saml/SAMLRequestParser.java
+++ b/saml-core/src/main/java/org/keycloak/saml/SAMLRequestParser.java
@@ -18,9 +18,11 @@
 package org.keycloak.saml;
 
 import org.jboss.logging.Logger;
+
 import org.keycloak.common.util.StreamUtil;
 import org.keycloak.saml.common.PicketLinkLogger;
 import org.keycloak.saml.common.PicketLinkLoggerFactory;
+import org.keycloak.saml.common.constants.GeneralConstants;
 import org.keycloak.saml.processing.api.saml.v2.request.SAML2Request;
 import org.keycloak.saml.processing.api.saml.v2.response.SAML2Response;
 import org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder;
@@ -45,13 +47,13 @@ public class SAMLRequestParser {
         if (log.isDebugEnabled()) {
             String message = null;
             try {
-                message = StreamUtil.readString(is);
+                message = StreamUtil.readString(is, GeneralConstants.SAML_CHARSET);
             } catch (IOException e) {
                 throw new RuntimeException(e);
             }
             log.debug("SAML Redirect Binding");
             log.debug(message);
-            is = new ByteArrayInputStream(message.getBytes());
+            is = new ByteArrayInputStream(message.getBytes(GeneralConstants.SAML_CHARSET));
 
         }
         SAML2Request saml2Request = new SAML2Request();
@@ -69,7 +71,7 @@ public class SAMLRequestParser {
         InputStream is;
         byte[] samlBytes = PostBindingUtil.base64Decode(samlMessage);
         if (log.isDebugEnabled()) {
-            String str = new String(samlBytes);
+            String str = new String(samlBytes, GeneralConstants.SAML_CHARSET);
             log.debug("SAML POST Binding");
             log.debug(str);
         }
@@ -92,7 +94,7 @@ public class SAMLRequestParser {
 
     public static SAMLDocumentHolder parseResponseDocument(byte[] samlBytes) {
         if (log.isDebugEnabled()) {
-            String str = new String(samlBytes);
+            String str = new String(samlBytes, GeneralConstants.SAML_CHARSET);
             log.debug(str);
         }
         InputStream is = new ByteArrayInputStream(samlBytes);
@@ -111,13 +113,13 @@ public class SAMLRequestParser {
         if (log.isDebugEnabled()) {
             String message = null;
             try {
-                message = StreamUtil.readString(is);
+                message = StreamUtil.readString(is, GeneralConstants.SAML_CHARSET);
             } catch (IOException e) {
                 throw new RuntimeException(e);
             }
             log.debug("SAML Redirect Binding");
             log.debug(message);
-            is = new ByteArrayInputStream(message.getBytes());
+            is = new ByteArrayInputStream(message.getBytes(GeneralConstants.SAML_CHARSET));
 
         }
         SAML2Response response = new SAML2Response();
diff --git a/saml-core/src/test/java/org/keycloak/saml/processing/core/parsers/saml/SAMLParserTest.java b/saml-core/src/test/java/org/keycloak/saml/processing/core/parsers/saml/SAMLParserTest.java
index 92f1a5e..51854fc 100644
--- a/saml-core/src/test/java/org/keycloak/saml/processing/core/parsers/saml/SAMLParserTest.java
+++ b/saml-core/src/test/java/org/keycloak/saml/processing/core/parsers/saml/SAMLParserTest.java
@@ -16,6 +16,8 @@
  */
 package org.keycloak.saml.processing.core.parsers.saml;
 
+import org.keycloak.dom.saml.v2.assertion.AssertionType;
+import org.keycloak.dom.saml.v2.assertion.NameIDType;
 import org.keycloak.dom.saml.v2.metadata.EntityDescriptorType;
 
 import java.io.InputStream;
@@ -27,8 +29,6 @@ import static org.hamcrest.CoreMatchers.*;
 import org.keycloak.dom.saml.v2.protocol.LogoutRequestType;
 import org.keycloak.dom.saml.v2.protocol.ResponseType;
 
-import java.io.IOException;
-import java.util.Scanner;
 import org.junit.Before;
 import org.w3c.dom.Element;
 
@@ -109,6 +109,38 @@ public class SAMLParserTest {
     }
 
     @Test
+    public void testSaml20AuthnResponseNonAsciiNameDefaultUtf8() throws Exception {
+        try (InputStream st = SAMLParserTest.class.getResourceAsStream("KEYCLOAK-3971-utf-8-no-header-authnresponse.xml")) {
+            Object parsedObject = parser.parse(st);
+            assertThat(parsedObject, instanceOf(ResponseType.class));
+
+            ResponseType rt = (ResponseType) parsedObject;
+            assertThat(rt.getAssertions().size(), is(1));
+            final AssertionType assertion = rt.getAssertions().get(0).getAssertion();
+            assertThat(assertion.getSubject().getSubType().getBaseID(), instanceOf(NameIDType.class));
+
+            NameIDType nameId = (NameIDType) assertion.getSubject().getSubType().getBaseID();
+            assertThat(nameId.getValue(), is("roàåאבčéèíñòøöùüßåäöü汉字"));
+        }
+    }
+
+    @Test
+    public void testSaml20AuthnResponseNonAsciiNameDefaultLatin2() throws Exception {
+        try (InputStream st = SAMLParserTest.class.getResourceAsStream("KEYCLOAK-3971-8859-2-in-header-authnresponse.xml")) {
+            Object parsedObject = parser.parse(st);
+            assertThat(parsedObject, instanceOf(ResponseType.class));
+
+            ResponseType rt = (ResponseType) parsedObject;
+            assertThat(rt.getAssertions().size(), is(1));
+            final AssertionType assertion = rt.getAssertions().get(0).getAssertion();
+            assertThat(assertion.getSubject().getSubType().getBaseID(), instanceOf(NameIDType.class));
+
+            NameIDType nameId = (NameIDType) assertion.getSubject().getSubType().getBaseID();
+            assertThat(nameId.getValue(), is("ročéíöüßäöü"));
+        }
+    }
+
+    @Test
     public void testSaml20PostLogoutRequest() throws Exception {
         try (InputStream st = SAMLParserTest.class.getResourceAsStream("saml20-signed-logout-request.xml")) {
             Object parsedObject = parser.parse(st);
diff --git a/saml-core/src/test/resources/org/keycloak/saml/processing/core/parsers/saml/KEYCLOAK-3971-8859-2-in-header-authnresponse.xml b/saml-core/src/test/resources/org/keycloak/saml/processing/core/parsers/saml/KEYCLOAK-3971-8859-2-in-header-authnresponse.xml
new file mode 100644
index 0000000..b4bc850
--- /dev/null
+++ b/saml-core/src/test/resources/org/keycloak/saml/processing/core/parsers/saml/KEYCLOAK-3971-8859-2-in-header-authnresponse.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="ISO-8859-2"?>
+<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Destination="http://localhost:8080/sales-post-sig/saml" ID="ID_670a76c7-8506-4081-80b3-5ef16df98af8" InResponseTo="ID_cc0ff6f7-b481-4c98-9a79-481d50958290" IssueInstant="2016-12-15T12:42:49.788Z" Version="2.0">
+    <saml:Issuer>http://localhost:11080/auth/realms/saml-demo</saml:Issuer>
+    <samlp:Status>
+        <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
+    </samlp:Status>
+    <saml:Assertion xmlns="urn:oasis:names:tc:SAML:2.0:assertion" ID="ID_cf2e2b00-dfb0-4163-b8b5-f2d85586a235" IssueInstant="2016-12-15T12:42:49.787Z" Version="2.0">
+        <saml:Issuer>http://localhost:11080/auth/realms/saml-demo</saml:Issuer>
+        <saml:Subject>
+            <saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">ro���������</saml:NameID>
+            <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
+                <saml:SubjectConfirmationData InResponseTo="ID_cc0ff6f7-b481-4c98-9a79-481d50958290" NotOnOrAfter="2016-12-15T12:47:47.787Z" Recipient="http://localhost:8080/sales-post-sig/saml"/>
+            </saml:SubjectConfirmation>
+        </saml:Subject>
+        <saml:Conditions NotBefore="2016-12-15T12:42:47.787Z" NotOnOrAfter="2016-12-15T12:43:47.787Z">
+            <saml:AudienceRestriction>
+                <saml:Audience>http://localhost:8080/sales-post-sig/</saml:Audience>
+            </saml:AudienceRestriction>
+        </saml:Conditions>
+        <saml:AuthnStatement AuthnInstant="2016-12-15T12:42:49.788Z" SessionIndex="fb5d5a23-aa34-4528-a29a-6aad8c0ef0e8">
+            <saml:AuthnContext>
+                <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</saml:AuthnContextClassRef>
+            </saml:AuthnContext>
+        </saml:AuthnStatement>
+        <saml:AttributeStatement>
+            <saml:Attribute Name="Role" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
+                <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">view-profile</saml:AttributeValue>
+            </saml:Attribute>
+        </saml:AttributeStatement>
+    </saml:Assertion>
+</samlp:Response>
\ No newline at end of file
diff --git a/saml-core/src/test/resources/org/keycloak/saml/processing/core/parsers/saml/KEYCLOAK-3971-utf-8-no-header-authnresponse.xml b/saml-core/src/test/resources/org/keycloak/saml/processing/core/parsers/saml/KEYCLOAK-3971-utf-8-no-header-authnresponse.xml
new file mode 100644
index 0000000..52dbb5c
--- /dev/null
+++ b/saml-core/src/test/resources/org/keycloak/saml/processing/core/parsers/saml/KEYCLOAK-3971-utf-8-no-header-authnresponse.xml
@@ -0,0 +1,30 @@
+<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Destination="http://localhost:8080/sales-post-sig/saml" ID="ID_670a76c7-8506-4081-80b3-5ef16df98af8" InResponseTo="ID_cc0ff6f7-b481-4c98-9a79-481d50958290" IssueInstant="2016-12-15T12:42:49.788Z" Version="2.0">
+    <saml:Issuer>http://localhost:11080/auth/realms/saml-demo</saml:Issuer>
+    <samlp:Status>
+        <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
+    </samlp:Status>
+    <saml:Assertion xmlns="urn:oasis:names:tc:SAML:2.0:assertion" ID="ID_cf2e2b00-dfb0-4163-b8b5-f2d85586a235" IssueInstant="2016-12-15T12:42:49.787Z" Version="2.0">
+        <saml:Issuer>http://localhost:11080/auth/realms/saml-demo</saml:Issuer>
+        <saml:Subject>
+            <saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">roàåאבčéèíñòøöùüßåäöü汉字</saml:NameID>
+            <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
+                <saml:SubjectConfirmationData InResponseTo="ID_cc0ff6f7-b481-4c98-9a79-481d50958290" NotOnOrAfter="2016-12-15T12:47:47.787Z" Recipient="http://localhost:8080/sales-post-sig/saml"/>
+            </saml:SubjectConfirmation>
+        </saml:Subject>
+        <saml:Conditions NotBefore="2016-12-15T12:42:47.787Z" NotOnOrAfter="2016-12-15T12:43:47.787Z">
+            <saml:AudienceRestriction>
+                <saml:Audience>http://localhost:8080/sales-post-sig/</saml:Audience>
+            </saml:AudienceRestriction>
+        </saml:Conditions>
+        <saml:AuthnStatement AuthnInstant="2016-12-15T12:42:49.788Z" SessionIndex="fb5d5a23-aa34-4528-a29a-6aad8c0ef0e8">
+            <saml:AuthnContext>
+                <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</saml:AuthnContextClassRef>
+            </saml:AuthnContext>
+        </saml:AuthnStatement>
+        <saml:AttributeStatement>
+            <saml:Attribute Name="Role" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
+                <saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">view-profile</saml:AttributeValue>
+            </saml:Attribute>
+        </saml:AttributeStatement>
+    </saml:Assertion>
+</samlp:Response>
\ No newline at end of file
diff --git a/saml-core-api/src/main/java/org/keycloak/saml/common/constants/GeneralConstants.java b/saml-core-api/src/main/java/org/keycloak/saml/common/constants/GeneralConstants.java
index accac66..c203c78 100755
--- a/saml-core-api/src/main/java/org/keycloak/saml/common/constants/GeneralConstants.java
+++ b/saml-core-api/src/main/java/org/keycloak/saml/common/constants/GeneralConstants.java
@@ -16,6 +16,7 @@
  */
 package org.keycloak.saml.common.constants;
 
+import java.nio.charset.Charset;
 
 /**
  * Constants
@@ -147,4 +148,7 @@ public interface GeneralConstants {
     String BASE64_ENCODE_WSTRUST_SECRET_KEY = "picketlink.wstrust.base64_encode_wstrust_secret_key";
 
     String HTTP_HEADER_X_REQUESTED_WITH = "X-Requested-With";
+
+    public static final String  SAML_CHARSET_NAME = System.getProperty("keycloak.saml.saml_message_charset", "UTF-8");
+    public static final Charset SAML_CHARSET = Charset.forName(SAML_CHARSET_NAME);
 }