KEYCLOAK-3971 Explicitly set encoding for SAML message processing
This commit is contained in:
parent
3c2a12d019
commit
7d51df4eed
23 changed files with 229 additions and 83 deletions
|
@ -40,7 +40,7 @@ public class SamlUtil {
|
||||||
httpFacade.getResponse().setHeader("Content-Type", "text/html");
|
httpFacade.getResponse().setHeader("Content-Type", "text/html");
|
||||||
httpFacade.getResponse().setHeader("Pragma", "no-cache");
|
httpFacade.getResponse().setHeader("Pragma", "no-cache");
|
||||||
httpFacade.getResponse().setHeader("Cache-Control", "no-cache, no-store");
|
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();
|
httpFacade.getResponse().end();
|
||||||
} else {
|
} else {
|
||||||
String uri = asRequest ? binding.redirectBinding(document).requestURI(actionUrl).toString() : binding.redirectBinding(document).responseURI(actionUrl).toString();
|
String uri = asRequest ? binding.redirectBinding(document).requestURI(actionUrl).toString() : binding.redirectBinding(document).responseURI(actionUrl).toString();
|
||||||
|
|
|
@ -21,6 +21,7 @@ import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
@ -28,18 +29,41 @@ import java.io.InputStreamReader;
|
||||||
*/
|
*/
|
||||||
public final class StreamUtil {
|
public final class StreamUtil {
|
||||||
|
|
||||||
|
private static final int BUFFER_LENGTH = 4096;
|
||||||
|
|
||||||
private StreamUtil() {
|
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
|
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();
|
StringBuilder builder = new StringBuilder();
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
|
BufferedReader reader = new BufferedReader(new InputStreamReader(in, charset));
|
||||||
int wasRead;
|
int wasRead;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
wasRead = reader.read(buffer, 0, 1024);
|
wasRead = reader.read(buffer, 0, BUFFER_LENGTH);
|
||||||
if (wasRead > 0)
|
if (wasRead > 0)
|
||||||
{
|
{
|
||||||
builder.append(buffer, 0, wasRead);
|
builder.append(buffer, 0, wasRead);
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
*/
|
*/
|
||||||
package org.keycloak.saml.common.constants;
|
package org.keycloak.saml.common.constants;
|
||||||
|
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constants
|
* Constants
|
||||||
|
@ -147,4 +148,7 @@ public interface GeneralConstants {
|
||||||
String BASE64_ENCODE_WSTRUST_SECRET_KEY = "picketlink.wstrust.base64_encode_wstrust_secret_key";
|
String BASE64_ENCODE_WSTRUST_SECRET_KEY = "picketlink.wstrust.base64_encode_wstrust_secret_key";
|
||||||
|
|
||||||
String HTTP_HEADER_X_REQUESTED_WITH = "X-Requested-With";
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
package org.keycloak.saml;
|
package org.keycloak.saml;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
import org.keycloak.common.util.KeycloakUriBuilder;
|
import org.keycloak.common.util.KeycloakUriBuilder;
|
||||||
import org.keycloak.saml.common.constants.GeneralConstants;
|
import org.keycloak.saml.common.constants.GeneralConstants;
|
||||||
import org.keycloak.saml.common.constants.JBossSAMLConstants;
|
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.core.util.XMLEncryptionUtil;
|
||||||
import org.keycloak.saml.processing.web.util.PostBindingUtil;
|
import org.keycloak.saml.processing.web.util.PostBindingUtil;
|
||||||
import org.keycloak.saml.processing.web.util.RedirectBindingUtil;
|
import org.keycloak.saml.processing.web.util.RedirectBindingUtil;
|
||||||
|
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
|
@ -38,7 +40,6 @@ import javax.crypto.spec.SecretKeySpec;
|
||||||
import javax.xml.crypto.dsig.CanonicalizationMethod;
|
import javax.xml.crypto.dsig.CanonicalizationMethod;
|
||||||
import javax.xml.namespace.QName;
|
import javax.xml.namespace.QName;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
|
@ -155,8 +156,8 @@ public class BaseSAML2BindingBuilder<T extends BaseSAML2BindingBuilder> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String encoded() throws ProcessingException, ConfigurationException, IOException {
|
public String encoded() throws ProcessingException, ConfigurationException, IOException {
|
||||||
byte[] responseBytes = DocumentUtil.getDocumentAsString(document).getBytes("UTF-8");
|
byte[] responseBytes = DocumentUtil.getDocumentAsString(document).getBytes(GeneralConstants.SAML_CHARSET);
|
||||||
return PostBindingUtil.base64Encode(new String(responseBytes));
|
return PostBindingUtil.base64Encode(new String(responseBytes, GeneralConstants.SAML_CHARSET));
|
||||||
}
|
}
|
||||||
public Document getDocument() {
|
public Document getDocument() {
|
||||||
return document;
|
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 {
|
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");
|
byte[] responseBytes = org.keycloak.saml.common.util.DocumentUtil.getDocumentAsString(responseDoc).getBytes(GeneralConstants.SAML_CHARSET);
|
||||||
String samlResponse = PostBindingUtil.base64Encode(new String(responseBytes));
|
String samlResponse = PostBindingUtil.base64Encode(new String(responseBytes, GeneralConstants.SAML_CHARSET));
|
||||||
|
|
||||||
return buildHtml(samlResponse, actionUrl, asRequest);
|
return buildHtml(samlResponse, actionUrl, asRequest);
|
||||||
}
|
}
|
||||||
|
@ -315,26 +316,26 @@ public class BaseSAML2BindingBuilder<T extends BaseSAML2BindingBuilder> {
|
||||||
key = GeneralConstants.SAML_REQUEST_KEY;
|
key = GeneralConstants.SAML_REQUEST_KEY;
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.append("<HTML>");
|
builder.append("<HTML>")
|
||||||
builder.append("<HEAD>");
|
.append("<HEAD>")
|
||||||
|
|
||||||
builder.append("<TITLE>SAML HTTP Post Binding</TITLE>");
|
.append("<TITLE>SAML HTTP Post Binding</TITLE>")
|
||||||
builder.append("</HEAD>");
|
.append("</HEAD>")
|
||||||
builder.append("<BODY Onload=\"document.forms[0].submit()\">");
|
.append("<BODY Onload=\"document.forms[0].submit()\">")
|
||||||
|
|
||||||
builder.append("<FORM METHOD=\"POST\" ACTION=\"" + actionUrl + "\">");
|
.append("<FORM METHOD=\"POST\" ACTION=\"").append(actionUrl).append("\">")
|
||||||
builder.append("<INPUT TYPE=\"HIDDEN\" NAME=\"" + key + "\"" + " VALUE=\"" + samlResponse + "\"/>");
|
.append("<INPUT TYPE=\"HIDDEN\" NAME=\"").append(key).append("\"").append(" VALUE=\"").append(samlResponse).append("\"/>");
|
||||||
|
|
||||||
if (isNotNull(relayState)) {
|
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("<NOSCRIPT>")
|
||||||
builder.append("<P>JavaScript is disabled. We strongly recommend to enable it. Click the button below to continue.</P>");
|
.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\" />");
|
.append("<INPUT TYPE=\"SUBMIT\" VALUE=\"CONTINUE\" />")
|
||||||
builder.append("</NOSCRIPT>");
|
.append("</NOSCRIPT>")
|
||||||
|
|
||||||
builder.append("</FORM></BODY></HTML>");
|
.append("</FORM></BODY></HTML>");
|
||||||
|
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
@ -342,7 +343,7 @@ public class BaseSAML2BindingBuilder<T extends BaseSAML2BindingBuilder> {
|
||||||
public String base64Encoded(Document document) throws ConfigurationException, ProcessingException, IOException {
|
public String base64Encoded(Document document) throws ConfigurationException, ProcessingException, IOException {
|
||||||
String documentAsString = DocumentUtil.getDocumentAsString(document);
|
String documentAsString = DocumentUtil.getDocumentAsString(document);
|
||||||
logger.debugv("saml document: {0}", documentAsString);
|
logger.debugv("saml document: {0}", documentAsString);
|
||||||
byte[] responseBytes = documentAsString.getBytes("UTF-8");
|
byte[] responseBytes = documentAsString.getBytes(GeneralConstants.SAML_CHARSET);
|
||||||
|
|
||||||
return RedirectBindingUtil.deflateBase64URLEncode(responseBytes);
|
return RedirectBindingUtil.deflateBase64URLEncode(responseBytes);
|
||||||
}
|
}
|
||||||
|
@ -364,9 +365,9 @@ public class BaseSAML2BindingBuilder<T extends BaseSAML2BindingBuilder> {
|
||||||
byte[] sig = new byte[0];
|
byte[] sig = new byte[0];
|
||||||
try {
|
try {
|
||||||
signature.initSign(signingKeyPair.getPrivate());
|
signature.initSign(signingKeyPair.getPrivate());
|
||||||
signature.update(rawQuery.getBytes("UTF-8"));
|
signature.update(rawQuery.getBytes(GeneralConstants.SAML_CHARSET));
|
||||||
sig = signature.sign();
|
sig = signature.sign();
|
||||||
} catch (InvalidKeyException | UnsupportedEncodingException | SignatureException e) {
|
} catch (InvalidKeyException | SignatureException e) {
|
||||||
throw new ProcessingException(e);
|
throw new ProcessingException(e);
|
||||||
}
|
}
|
||||||
String encodedSig = RedirectBindingUtil.base64URLEncode(sig);
|
String encodedSig = RedirectBindingUtil.base64URLEncode(sig);
|
||||||
|
|
|
@ -18,9 +18,11 @@
|
||||||
package org.keycloak.saml;
|
package org.keycloak.saml;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
import org.keycloak.common.util.StreamUtil;
|
import org.keycloak.common.util.StreamUtil;
|
||||||
import org.keycloak.saml.common.PicketLinkLogger;
|
import org.keycloak.saml.common.PicketLinkLogger;
|
||||||
import org.keycloak.saml.common.PicketLinkLoggerFactory;
|
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.request.SAML2Request;
|
||||||
import org.keycloak.saml.processing.api.saml.v2.response.SAML2Response;
|
import org.keycloak.saml.processing.api.saml.v2.response.SAML2Response;
|
||||||
import org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder;
|
import org.keycloak.saml.processing.core.saml.v2.common.SAMLDocumentHolder;
|
||||||
|
@ -45,13 +47,13 @@ public class SAMLRequestParser {
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
String message = null;
|
String message = null;
|
||||||
try {
|
try {
|
||||||
message = StreamUtil.readString(is);
|
message = StreamUtil.readString(is, GeneralConstants.SAML_CHARSET);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
log.debug("SAML Redirect Binding");
|
log.debug("SAML Redirect Binding");
|
||||||
log.debug(message);
|
log.debug(message);
|
||||||
is = new ByteArrayInputStream(message.getBytes());
|
is = new ByteArrayInputStream(message.getBytes(GeneralConstants.SAML_CHARSET));
|
||||||
|
|
||||||
}
|
}
|
||||||
SAML2Request saml2Request = new SAML2Request();
|
SAML2Request saml2Request = new SAML2Request();
|
||||||
|
@ -69,7 +71,7 @@ public class SAMLRequestParser {
|
||||||
InputStream is;
|
InputStream is;
|
||||||
byte[] samlBytes = PostBindingUtil.base64Decode(samlMessage);
|
byte[] samlBytes = PostBindingUtil.base64Decode(samlMessage);
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
String str = new String(samlBytes);
|
String str = new String(samlBytes, GeneralConstants.SAML_CHARSET);
|
||||||
log.debug("SAML POST Binding");
|
log.debug("SAML POST Binding");
|
||||||
log.debug(str);
|
log.debug(str);
|
||||||
}
|
}
|
||||||
|
@ -92,7 +94,7 @@ public class SAMLRequestParser {
|
||||||
|
|
||||||
public static SAMLDocumentHolder parseResponseDocument(byte[] samlBytes) {
|
public static SAMLDocumentHolder parseResponseDocument(byte[] samlBytes) {
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
String str = new String(samlBytes);
|
String str = new String(samlBytes, GeneralConstants.SAML_CHARSET);
|
||||||
log.debug(str);
|
log.debug(str);
|
||||||
}
|
}
|
||||||
InputStream is = new ByteArrayInputStream(samlBytes);
|
InputStream is = new ByteArrayInputStream(samlBytes);
|
||||||
|
@ -111,13 +113,13 @@ public class SAMLRequestParser {
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
String message = null;
|
String message = null;
|
||||||
try {
|
try {
|
||||||
message = StreamUtil.readString(is);
|
message = StreamUtil.readString(is, GeneralConstants.SAML_CHARSET);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
log.debug("SAML Redirect Binding");
|
log.debug("SAML Redirect Binding");
|
||||||
log.debug(message);
|
log.debug(message);
|
||||||
is = new ByteArrayInputStream(message.getBytes());
|
is = new ByteArrayInputStream(message.getBytes(GeneralConstants.SAML_CHARSET));
|
||||||
|
|
||||||
}
|
}
|
||||||
SAML2Response response = new SAML2Response();
|
SAML2Response response = new SAML2Response();
|
||||||
|
|
|
@ -376,7 +376,7 @@ public class DocumentUtil {
|
||||||
throw logger.processingError(e);
|
throw logger.processingError(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new String(baos.toByteArray());
|
return new String(baos.toByteArray(), GeneralConstants.SAML_CHARSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -75,7 +75,7 @@ public class StaxUtil {
|
||||||
public static XMLEventWriter getXMLEventWriter(final OutputStream outStream) throws ProcessingException {
|
public static XMLEventWriter getXMLEventWriter(final OutputStream outStream) throws ProcessingException {
|
||||||
XMLOutputFactory xmlOutputFactory = getXMLOutputFactory();
|
XMLOutputFactory xmlOutputFactory = getXMLOutputFactory();
|
||||||
try {
|
try {
|
||||||
return xmlOutputFactory.createXMLEventWriter(outStream, "UTF-8");
|
return xmlOutputFactory.createXMLEventWriter(outStream, GeneralConstants.SAML_CHARSET_NAME);
|
||||||
} catch (XMLStreamException e) {
|
} catch (XMLStreamException e) {
|
||||||
throw logger.processingError(e);
|
throw logger.processingError(e);
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ public class StaxUtil {
|
||||||
public static XMLStreamWriter getXMLStreamWriter(final OutputStream outStream) throws ProcessingException {
|
public static XMLStreamWriter getXMLStreamWriter(final OutputStream outStream) throws ProcessingException {
|
||||||
XMLOutputFactory xmlOutputFactory = getXMLOutputFactory();
|
XMLOutputFactory xmlOutputFactory = getXMLOutputFactory();
|
||||||
try {
|
try {
|
||||||
return xmlOutputFactory.createXMLStreamWriter(outStream, "UTF-8");
|
return xmlOutputFactory.createXMLStreamWriter(outStream, GeneralConstants.SAML_CHARSET_NAME);
|
||||||
} catch (XMLStreamException e) {
|
} catch (XMLStreamException e) {
|
||||||
throw logger.processingError(e);
|
throw logger.processingError(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.keycloak.dom.saml.v2.protocol.RequestAbstractType;
|
||||||
import org.keycloak.dom.saml.v2.protocol.ResponseType;
|
import org.keycloak.dom.saml.v2.protocol.ResponseType;
|
||||||
import org.keycloak.saml.common.PicketLinkLogger;
|
import org.keycloak.saml.common.PicketLinkLogger;
|
||||||
import org.keycloak.saml.common.PicketLinkLoggerFactory;
|
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.JBossSAMLConstants;
|
||||||
import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
|
import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
|
||||||
import org.keycloak.saml.common.exceptions.ConfigurationException;
|
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.SAMLRequestWriter;
|
||||||
import org.keycloak.saml.processing.core.saml.v2.writers.SAMLResponseWriter;
|
import org.keycloak.saml.processing.core.saml.v2.writers.SAMLResponseWriter;
|
||||||
import org.keycloak.saml.processing.core.util.JAXPValidationUtil;
|
import org.keycloak.saml.processing.core.util.JAXPValidationUtil;
|
||||||
|
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
|
|
||||||
import javax.xml.datatype.XMLGregorianCalendar;
|
import javax.xml.datatype.XMLGregorianCalendar;
|
||||||
|
@ -274,7 +276,7 @@ public class SAML2Request {
|
||||||
writer.write((LogoutRequestType) rat);
|
writer.write((LogoutRequestType) rat);
|
||||||
}
|
}
|
||||||
|
|
||||||
return DocumentUtil.getDocument(new String(bos.toByteArray()));
|
return DocumentUtil.getDocument(new String(bos.toByteArray(), GeneralConstants.SAML_CHARSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
*/
|
*/
|
||||||
package org.keycloak.saml.processing.api.util;
|
package org.keycloak.saml.processing.api.util;
|
||||||
|
|
||||||
|
import org.keycloak.saml.common.constants.GeneralConstants;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -62,7 +64,7 @@ public class DeflateUtil {
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public static byte[] encode(String message) throws IOException {
|
public static byte[] encode(String message) throws IOException {
|
||||||
return encode(message.getBytes());
|
return encode(message.getBytes(GeneralConstants.SAML_CHARSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -37,6 +37,7 @@ import org.keycloak.dom.saml.v2.metadata.SPSSODescriptorType;
|
||||||
import org.keycloak.dom.xmlsec.w3.xmlenc.EncryptionMethodType;
|
import org.keycloak.dom.xmlsec.w3.xmlenc.EncryptionMethodType;
|
||||||
import org.keycloak.saml.common.PicketLinkLogger;
|
import org.keycloak.saml.common.PicketLinkLogger;
|
||||||
import org.keycloak.saml.common.PicketLinkLoggerFactory;
|
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.JBossSAMLConstants;
|
||||||
import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
|
import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
|
||||||
import org.keycloak.saml.common.exceptions.ParsingException;
|
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.common.util.StaxParserUtil;
|
||||||
import org.keycloak.saml.processing.core.parsers.util.SAMLParserUtil;
|
import org.keycloak.saml.processing.core.parsers.util.SAMLParserUtil;
|
||||||
import org.keycloak.saml.processing.core.saml.v2.util.XMLTimeUtil;
|
import org.keycloak.saml.processing.core.saml.v2.util.XMLTimeUtil;
|
||||||
|
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
import javax.xml.namespace.QName;
|
import javax.xml.namespace.QName;
|
||||||
|
@ -476,7 +478,7 @@ public class SAMLEntityDescriptorParser extends AbstractDescriptorParser impleme
|
||||||
keySize = BigInteger.valueOf(Long.valueOf(StaxParserUtil.getElementText(xmlEventReader)));
|
keySize = BigInteger.valueOf(Long.valueOf(StaxParserUtil.getElementText(xmlEventReader)));
|
||||||
} else if ("OAEPparams".equals(localPart)) {
|
} else if ("OAEPparams".equals(localPart)) {
|
||||||
startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
|
startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
|
||||||
OAEPparams = StaxParserUtil.getElementText(xmlEventReader).getBytes();
|
OAEPparams = StaxParserUtil.getElementText(xmlEventReader).getBytes(GeneralConstants.SAML_CHARSET);
|
||||||
} else {
|
} else {
|
||||||
throw logger.parserUnknownTag(localPart, startElement.getLocation());
|
throw logger.parserUnknownTag(localPart, startElement.getLocation());
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ import org.keycloak.dom.xmlsec.w3.xmldsig.X509CertificateType;
|
||||||
import org.keycloak.dom.xmlsec.w3.xmldsig.X509DataType;
|
import org.keycloak.dom.xmlsec.w3.xmldsig.X509DataType;
|
||||||
import org.keycloak.saml.common.PicketLinkLogger;
|
import org.keycloak.saml.common.PicketLinkLogger;
|
||||||
import org.keycloak.saml.common.PicketLinkLoggerFactory;
|
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.JBossSAMLConstants;
|
||||||
import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
|
import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
|
||||||
import org.keycloak.saml.common.constants.WSTrustConstants;
|
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.v1.SAML11Constants;
|
||||||
import org.keycloak.saml.processing.core.saml.v2.util.SignatureUtil;
|
import org.keycloak.saml.processing.core.saml.v2.util.SignatureUtil;
|
||||||
import org.keycloak.saml.processing.core.saml.v2.util.XMLTimeUtil;
|
import org.keycloak.saml.processing.core.saml.v2.util.XMLTimeUtil;
|
||||||
|
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
import javax.xml.namespace.QName;
|
import javax.xml.namespace.QName;
|
||||||
|
@ -561,7 +563,7 @@ public class SAML11ParserUtil {
|
||||||
|
|
||||||
X509CertificateType cert = new X509CertificateType();
|
X509CertificateType cert = new X509CertificateType();
|
||||||
String certValue = StaxParserUtil.getElementText(xmlEventReader);
|
String certValue = StaxParserUtil.getElementText(xmlEventReader);
|
||||||
cert.setEncodedCertificate(certValue.getBytes());
|
cert.setEncodedCertificate(certValue.getBytes(GeneralConstants.SAML_CHARSET));
|
||||||
x509.add(cert);
|
x509.add(cert);
|
||||||
|
|
||||||
EndElement endElement = StaxParserUtil.getNextEndElement(xmlEventReader);
|
EndElement endElement = StaxParserUtil.getNextEndElement(xmlEventReader);
|
||||||
|
@ -614,11 +616,11 @@ public class SAML11ParserUtil {
|
||||||
if (tag.equals(WSTrustConstants.XMLDSig.MODULUS)) {
|
if (tag.equals(WSTrustConstants.XMLDSig.MODULUS)) {
|
||||||
startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
|
startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
|
||||||
String text = StaxParserUtil.getElementText(xmlEventReader);
|
String text = StaxParserUtil.getElementText(xmlEventReader);
|
||||||
rsaKeyValue.setModulus(text.getBytes());
|
rsaKeyValue.setModulus(text.getBytes(GeneralConstants.SAML_CHARSET));
|
||||||
} else if (tag.equals(WSTrustConstants.XMLDSig.EXPONENT)) {
|
} else if (tag.equals(WSTrustConstants.XMLDSig.EXPONENT)) {
|
||||||
startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
|
startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
|
||||||
String text = StaxParserUtil.getElementText(xmlEventReader);
|
String text = StaxParserUtil.getElementText(xmlEventReader);
|
||||||
rsaKeyValue.setExponent(text.getBytes());
|
rsaKeyValue.setExponent(text.getBytes(GeneralConstants.SAML_CHARSET));
|
||||||
} else
|
} else
|
||||||
throw logger.parserUnknownTag(tag, startElement.getLocation());
|
throw logger.parserUnknownTag(tag, startElement.getLocation());
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ import org.keycloak.dom.xmlsec.w3.xmldsig.X509CertificateType;
|
||||||
import org.keycloak.dom.xmlsec.w3.xmldsig.X509DataType;
|
import org.keycloak.dom.xmlsec.w3.xmldsig.X509DataType;
|
||||||
import org.keycloak.saml.common.PicketLinkLogger;
|
import org.keycloak.saml.common.PicketLinkLogger;
|
||||||
import org.keycloak.saml.common.PicketLinkLoggerFactory;
|
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.JBossSAMLConstants;
|
||||||
import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
|
import org.keycloak.saml.common.constants.JBossSAMLURIConstants;
|
||||||
import org.keycloak.saml.common.constants.WSTrustConstants;
|
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.common.util.StringUtil;
|
||||||
import org.keycloak.saml.processing.core.saml.v2.util.SignatureUtil;
|
import org.keycloak.saml.processing.core.saml.v2.util.SignatureUtil;
|
||||||
import org.keycloak.saml.processing.core.saml.v2.util.XMLTimeUtil;
|
import org.keycloak.saml.processing.core.saml.v2.util.XMLTimeUtil;
|
||||||
|
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
import javax.xml.datatype.XMLGregorianCalendar;
|
import javax.xml.datatype.XMLGregorianCalendar;
|
||||||
|
@ -98,7 +100,7 @@ public class SAMLParserUtil {
|
||||||
|
|
||||||
X509CertificateType cert = new X509CertificateType();
|
X509CertificateType cert = new X509CertificateType();
|
||||||
String certValue = StaxParserUtil.getElementText(xmlEventReader);
|
String certValue = StaxParserUtil.getElementText(xmlEventReader);
|
||||||
cert.setEncodedCertificate(certValue.getBytes());
|
cert.setEncodedCertificate(certValue.getBytes(GeneralConstants.SAML_CHARSET));
|
||||||
x509.add(cert);
|
x509.add(cert);
|
||||||
|
|
||||||
EndElement endElement = StaxParserUtil.getNextEndElement(xmlEventReader);
|
EndElement endElement = StaxParserUtil.getNextEndElement(xmlEventReader);
|
||||||
|
@ -151,11 +153,11 @@ public class SAMLParserUtil {
|
||||||
if (tag.equals(WSTrustConstants.XMLDSig.MODULUS)) {
|
if (tag.equals(WSTrustConstants.XMLDSig.MODULUS)) {
|
||||||
startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
|
startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
|
||||||
String text = StaxParserUtil.getElementText(xmlEventReader);
|
String text = StaxParserUtil.getElementText(xmlEventReader);
|
||||||
rsaKeyValue.setModulus(text.getBytes());
|
rsaKeyValue.setModulus(text.getBytes(GeneralConstants.SAML_CHARSET));
|
||||||
} else if (tag.equals(WSTrustConstants.XMLDSig.EXPONENT)) {
|
} else if (tag.equals(WSTrustConstants.XMLDSig.EXPONENT)) {
|
||||||
startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
|
startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
|
||||||
String text = StaxParserUtil.getElementText(xmlEventReader);
|
String text = StaxParserUtil.getElementText(xmlEventReader);
|
||||||
rsaKeyValue.setExponent(text.getBytes());
|
rsaKeyValue.setExponent(text.getBytes(GeneralConstants.SAML_CHARSET));
|
||||||
} else
|
} else
|
||||||
throw logger.parserUnknownTag(tag, startElement.getLocation());
|
throw logger.parserUnknownTag(tag, startElement.getLocation());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.saml.v2.writers.SAMLAssertionWriter;
|
||||||
import org.keycloak.saml.processing.core.util.JAXPValidationUtil;
|
import org.keycloak.saml.processing.core.util.JAXPValidationUtil;
|
||||||
import org.keycloak.saml.processing.core.util.XMLEncryptionUtil;
|
import org.keycloak.saml.processing.core.util.XMLEncryptionUtil;
|
||||||
|
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
|
@ -62,7 +63,9 @@ import java.security.PublicKey;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.keycloak.rotation.HardcodedKeyLocator;
|
import org.keycloak.rotation.HardcodedKeyLocator;
|
||||||
|
import org.keycloak.saml.common.constants.GeneralConstants;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility to deal with assertions
|
* Utility to deal with assertions
|
||||||
|
@ -87,7 +90,7 @@ public class AssertionUtil {
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
SAMLAssertionWriter writer = new SAMLAssertionWriter(StaxUtil.getXMLStreamWriter(baos));
|
SAMLAssertionWriter writer = new SAMLAssertionWriter(StaxUtil.getXMLStreamWriter(baos));
|
||||||
writer.write(assertion);
|
writer.write(assertion);
|
||||||
return new String(baos.toByteArray());
|
return new String(baos.toByteArray(), GeneralConstants.SAML_CHARSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -22,11 +22,13 @@ import org.keycloak.dom.xmlsec.w3.xmldsig.RSAKeyValueType;
|
||||||
import org.keycloak.dom.xmlsec.w3.xmldsig.SignatureType;
|
import org.keycloak.dom.xmlsec.w3.xmldsig.SignatureType;
|
||||||
import org.keycloak.saml.common.PicketLinkLogger;
|
import org.keycloak.saml.common.PicketLinkLogger;
|
||||||
import org.keycloak.saml.common.PicketLinkLoggerFactory;
|
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.JBossSAMLConstants;
|
||||||
import org.keycloak.saml.common.constants.WSTrustConstants;
|
import org.keycloak.saml.common.constants.WSTrustConstants;
|
||||||
import org.keycloak.saml.common.exceptions.ParsingException;
|
import org.keycloak.saml.common.exceptions.ParsingException;
|
||||||
import org.keycloak.saml.common.util.Base64;
|
import org.keycloak.saml.common.util.Base64;
|
||||||
import org.keycloak.saml.processing.core.constants.PicketLinkFederationConstants;
|
import org.keycloak.saml.processing.core.constants.PicketLinkFederationConstants;
|
||||||
|
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
import org.w3c.dom.NodeList;
|
import org.w3c.dom.NodeList;
|
||||||
|
@ -106,7 +108,7 @@ public class SignatureUtil {
|
||||||
String algo = signingKey.getAlgorithm();
|
String algo = signingKey.getAlgorithm();
|
||||||
Signature sig = getSignature(algo);
|
Signature sig = getSignature(algo);
|
||||||
sig.initSign(signingKey);
|
sig.initSign(signingKey);
|
||||||
sig.update(stringToBeSigned.getBytes());
|
sig.update(stringToBeSigned.getBytes(GeneralConstants.SAML_CHARSET));
|
||||||
return sig.sign();
|
return sig.sign();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,7 +193,7 @@ public class SignatureUtil {
|
||||||
Element childElement = (Element) node;
|
Element childElement = (Element) node;
|
||||||
String tag = childElement.getLocalName();
|
String tag = childElement.getLocalName();
|
||||||
|
|
||||||
byte[] text = childElement.getTextContent().getBytes();
|
byte[] text = childElement.getTextContent().getBytes(GeneralConstants.SAML_CHARSET);
|
||||||
|
|
||||||
if (WSTrustConstants.XMLDSig.P.equals(tag)) {
|
if (WSTrustConstants.XMLDSig.P.equals(tag)) {
|
||||||
dsa.setP(text);
|
dsa.setP(text);
|
||||||
|
@ -232,7 +234,7 @@ public class SignatureUtil {
|
||||||
Element childElement = (Element) node;
|
Element childElement = (Element) node;
|
||||||
String tag = childElement.getLocalName();
|
String tag = childElement.getLocalName();
|
||||||
|
|
||||||
byte[] text = childElement.getTextContent().getBytes();
|
byte[] text = childElement.getTextContent().getBytes(GeneralConstants.SAML_CHARSET);
|
||||||
|
|
||||||
if (WSTrustConstants.XMLDSig.MODULUS.equals(tag)) {
|
if (WSTrustConstants.XMLDSig.MODULUS.equals(tag)) {
|
||||||
rsa.setModulus(text);
|
rsa.setModulus(text);
|
||||||
|
@ -262,8 +264,8 @@ public class SignatureUtil {
|
||||||
byte[] exponent = pubKey.getPublicExponent().toByteArray();
|
byte[] exponent = pubKey.getPublicExponent().toByteArray();
|
||||||
|
|
||||||
RSAKeyValueType rsaKeyValue = new RSAKeyValueType();
|
RSAKeyValueType rsaKeyValue = new RSAKeyValueType();
|
||||||
rsaKeyValue.setModulus(Base64.encodeBytes(modulus).getBytes());
|
rsaKeyValue.setModulus(Base64.encodeBytes(modulus).getBytes(GeneralConstants.SAML_CHARSET));
|
||||||
rsaKeyValue.setExponent(Base64.encodeBytes(exponent).getBytes());
|
rsaKeyValue.setExponent(Base64.encodeBytes(exponent).getBytes(GeneralConstants.SAML_CHARSET));
|
||||||
return rsaKeyValue;
|
return rsaKeyValue;
|
||||||
} else if (key instanceof DSAPublicKey) {
|
} else if (key instanceof DSAPublicKey) {
|
||||||
DSAPublicKey pubKey = (DSAPublicKey) key;
|
DSAPublicKey pubKey = (DSAPublicKey) key;
|
||||||
|
@ -273,10 +275,10 @@ public class SignatureUtil {
|
||||||
byte[] Y = pubKey.getY().toByteArray();
|
byte[] Y = pubKey.getY().toByteArray();
|
||||||
|
|
||||||
DSAKeyValueType dsaKeyValue = new DSAKeyValueType();
|
DSAKeyValueType dsaKeyValue = new DSAKeyValueType();
|
||||||
dsaKeyValue.setP(Base64.encodeBytes(P).getBytes());
|
dsaKeyValue.setP(Base64.encodeBytes(P).getBytes(GeneralConstants.SAML_CHARSET));
|
||||||
dsaKeyValue.setQ(Base64.encodeBytes(Q).getBytes());
|
dsaKeyValue.setQ(Base64.encodeBytes(Q).getBytes(GeneralConstants.SAML_CHARSET));
|
||||||
dsaKeyValue.setG(Base64.encodeBytes(G).getBytes());
|
dsaKeyValue.setG(Base64.encodeBytes(G).getBytes(GeneralConstants.SAML_CHARSET));
|
||||||
dsaKeyValue.setY(Base64.encodeBytes(Y).getBytes());
|
dsaKeyValue.setY(Base64.encodeBytes(Y).getBytes(GeneralConstants.SAML_CHARSET));
|
||||||
return dsaKeyValue;
|
return dsaKeyValue;
|
||||||
}
|
}
|
||||||
throw logger.unsupportedType(key.toString());
|
throw logger.unsupportedType(key.toString());
|
||||||
|
|
|
@ -27,9 +27,11 @@ import org.keycloak.dom.xmlsec.w3.xmldsig.X509DataType;
|
||||||
import org.keycloak.saml.common.ErrorCodes;
|
import org.keycloak.saml.common.ErrorCodes;
|
||||||
import org.keycloak.saml.common.PicketLinkLogger;
|
import org.keycloak.saml.common.PicketLinkLogger;
|
||||||
import org.keycloak.saml.common.PicketLinkLoggerFactory;
|
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.constants.WSTrustConstants;
|
||||||
import org.keycloak.saml.common.exceptions.ProcessingException;
|
import org.keycloak.saml.common.exceptions.ProcessingException;
|
||||||
import org.keycloak.saml.common.util.StaxUtil;
|
import org.keycloak.saml.common.util.StaxUtil;
|
||||||
|
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
import javax.xml.stream.XMLStreamWriter;
|
import javax.xml.stream.XMLStreamWriter;
|
||||||
|
@ -77,7 +79,7 @@ public class StaxWriterUtil {
|
||||||
X509CertificateType cert = (X509CertificateType) obj;
|
X509CertificateType cert = (X509CertificateType) obj;
|
||||||
StaxUtil.writeStartElement(writer, WSTrustConstants.XMLDSig.DSIG_PREFIX, WSTrustConstants.XMLDSig.X509CERT,
|
StaxUtil.writeStartElement(writer, WSTrustConstants.XMLDSig.DSIG_PREFIX, WSTrustConstants.XMLDSig.X509CERT,
|
||||||
WSTrustConstants.XMLDSig.DSIG_NS);
|
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);
|
||||||
}
|
}
|
||||||
StaxUtil.writeEndElement(writer);
|
StaxUtil.writeEndElement(writer);
|
||||||
|
@ -105,13 +107,13 @@ public class StaxWriterUtil {
|
||||||
// write the rsa key modulus.
|
// write the rsa key modulus.
|
||||||
byte[] modulus = type.getModulus();
|
byte[] modulus = type.getModulus();
|
||||||
StaxUtil.writeStartElement(writer, prefix, WSTrustConstants.XMLDSig.MODULUS, WSTrustConstants.DSIG_NS);
|
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);
|
StaxUtil.writeEndElement(writer);
|
||||||
|
|
||||||
// write the rsa key exponent.
|
// write the rsa key exponent.
|
||||||
byte[] exponent = type.getExponent();
|
byte[] exponent = type.getExponent();
|
||||||
StaxUtil.writeStartElement(writer, prefix, WSTrustConstants.XMLDSig.EXPONENT, WSTrustConstants.DSIG_NS);
|
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);
|
||||||
|
|
||||||
StaxUtil.writeEndElement(writer);
|
StaxUtil.writeEndElement(writer);
|
||||||
|
@ -126,37 +128,37 @@ public class StaxWriterUtil {
|
||||||
byte[] p = type.getP();
|
byte[] p = type.getP();
|
||||||
if (p != null) {
|
if (p != null) {
|
||||||
StaxUtil.writeStartElement(writer, prefix, WSTrustConstants.XMLDSig.P, WSTrustConstants.DSIG_NS);
|
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);
|
StaxUtil.writeEndElement(writer);
|
||||||
}
|
}
|
||||||
byte[] q = type.getQ();
|
byte[] q = type.getQ();
|
||||||
if (q != null) {
|
if (q != null) {
|
||||||
StaxUtil.writeStartElement(writer, prefix, WSTrustConstants.XMLDSig.Q, WSTrustConstants.DSIG_NS);
|
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);
|
StaxUtil.writeEndElement(writer);
|
||||||
}
|
}
|
||||||
byte[] g = type.getG();
|
byte[] g = type.getG();
|
||||||
if (g != null) {
|
if (g != null) {
|
||||||
StaxUtil.writeStartElement(writer, prefix, WSTrustConstants.XMLDSig.G, WSTrustConstants.DSIG_NS);
|
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);
|
StaxUtil.writeEndElement(writer);
|
||||||
}
|
}
|
||||||
byte[] y = type.getY();
|
byte[] y = type.getY();
|
||||||
if (y != null) {
|
if (y != null) {
|
||||||
StaxUtil.writeStartElement(writer, prefix, WSTrustConstants.XMLDSig.Y, WSTrustConstants.DSIG_NS);
|
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);
|
StaxUtil.writeEndElement(writer);
|
||||||
}
|
}
|
||||||
byte[] seed = type.getSeed();
|
byte[] seed = type.getSeed();
|
||||||
if (seed != null) {
|
if (seed != null) {
|
||||||
StaxUtil.writeStartElement(writer, prefix, WSTrustConstants.XMLDSig.SEED, WSTrustConstants.DSIG_NS);
|
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);
|
StaxUtil.writeEndElement(writer);
|
||||||
}
|
}
|
||||||
byte[] pgen = type.getPgenCounter();
|
byte[] pgen = type.getPgenCounter();
|
||||||
if (pgen != null) {
|
if (pgen != null) {
|
||||||
StaxUtil.writeStartElement(writer, prefix, WSTrustConstants.XMLDSig.PGEN_COUNTER, WSTrustConstants.DSIG_NS);
|
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);
|
StaxUtil.writeEndElement(writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,8 @@ package org.keycloak.saml.processing.core.util;
|
||||||
|
|
||||||
import org.keycloak.saml.common.PicketLinkLogger;
|
import org.keycloak.saml.common.PicketLinkLogger;
|
||||||
import org.keycloak.saml.common.PicketLinkLoggerFactory;
|
import org.keycloak.saml.common.PicketLinkLoggerFactory;
|
||||||
|
import org.keycloak.saml.common.constants.GeneralConstants;
|
||||||
|
|
||||||
import org.xml.sax.ErrorHandler;
|
import org.xml.sax.ErrorHandler;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
import org.xml.sax.SAXParseException;
|
import org.xml.sax.SAXParseException;
|
||||||
|
@ -89,7 +91,7 @@ public class JAXBUtil {
|
||||||
|
|
||||||
JAXBContext jc = getJAXBContext(pkgName);
|
JAXBContext jc = getJAXBContext(pkgName);
|
||||||
Marshaller marshaller = jc.createMarshaller();
|
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
|
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.FALSE); // Breaks signatures
|
||||||
return marshaller;
|
return marshaller;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ import org.keycloak.dom.xmlsec.w3.xmldsig.RSAKeyValueType;
|
||||||
import org.keycloak.dom.xmlsec.w3.xmldsig.SignatureType;
|
import org.keycloak.dom.xmlsec.w3.xmldsig.SignatureType;
|
||||||
import org.keycloak.saml.common.PicketLinkLogger;
|
import org.keycloak.saml.common.PicketLinkLogger;
|
||||||
import org.keycloak.saml.common.PicketLinkLoggerFactory;
|
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.JBossSAMLConstants;
|
||||||
import org.keycloak.saml.common.constants.WSTrustConstants;
|
import org.keycloak.saml.common.constants.WSTrustConstants;
|
||||||
import org.keycloak.saml.common.exceptions.ParsingException;
|
import org.keycloak.saml.common.exceptions.ParsingException;
|
||||||
|
@ -572,7 +573,7 @@ public class XMLSignatureUtil {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
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) {
|
while (bais.available() > 0) {
|
||||||
cert = (X509Certificate) cf.generateCertificate(bais);
|
cert = (X509Certificate) cf.generateCertificate(bais);
|
||||||
|
@ -603,7 +604,7 @@ public class XMLSignatureUtil {
|
||||||
Element childElement = (Element) node;
|
Element childElement = (Element) node;
|
||||||
String tag = childElement.getLocalName();
|
String tag = childElement.getLocalName();
|
||||||
|
|
||||||
byte[] text = childElement.getTextContent().getBytes();
|
byte[] text = childElement.getTextContent().getBytes(GeneralConstants.SAML_CHARSET);
|
||||||
|
|
||||||
if (WSTrustConstants.XMLDSig.P.equals(tag)) {
|
if (WSTrustConstants.XMLDSig.P.equals(tag)) {
|
||||||
dsa.setP(text);
|
dsa.setP(text);
|
||||||
|
@ -644,7 +645,7 @@ public class XMLSignatureUtil {
|
||||||
Element childElement = (Element) node;
|
Element childElement = (Element) node;
|
||||||
String tag = childElement.getLocalName();
|
String tag = childElement.getLocalName();
|
||||||
|
|
||||||
byte[] text = childElement.getTextContent().getBytes();
|
byte[] text = childElement.getTextContent().getBytes(GeneralConstants.SAML_CHARSET);
|
||||||
|
|
||||||
if (WSTrustConstants.XMLDSig.MODULUS.equals(tag)) {
|
if (WSTrustConstants.XMLDSig.MODULUS.equals(tag)) {
|
||||||
rsa.setModulus(text);
|
rsa.setModulus(text);
|
||||||
|
@ -674,8 +675,8 @@ public class XMLSignatureUtil {
|
||||||
byte[] exponent = pubKey.getPublicExponent().toByteArray();
|
byte[] exponent = pubKey.getPublicExponent().toByteArray();
|
||||||
|
|
||||||
RSAKeyValueType rsaKeyValue = new RSAKeyValueType();
|
RSAKeyValueType rsaKeyValue = new RSAKeyValueType();
|
||||||
rsaKeyValue.setModulus(Base64.encodeBytes(modulus).getBytes());
|
rsaKeyValue.setModulus(Base64.encodeBytes(modulus).getBytes(GeneralConstants.SAML_CHARSET));
|
||||||
rsaKeyValue.setExponent(Base64.encodeBytes(exponent).getBytes());
|
rsaKeyValue.setExponent(Base64.encodeBytes(exponent).getBytes(GeneralConstants.SAML_CHARSET));
|
||||||
return rsaKeyValue;
|
return rsaKeyValue;
|
||||||
} else if (key instanceof DSAPublicKey) {
|
} else if (key instanceof DSAPublicKey) {
|
||||||
DSAPublicKey pubKey = (DSAPublicKey) key;
|
DSAPublicKey pubKey = (DSAPublicKey) key;
|
||||||
|
@ -685,10 +686,10 @@ public class XMLSignatureUtil {
|
||||||
byte[] Y = pubKey.getY().toByteArray();
|
byte[] Y = pubKey.getY().toByteArray();
|
||||||
|
|
||||||
DSAKeyValueType dsaKeyValue = new DSAKeyValueType();
|
DSAKeyValueType dsaKeyValue = new DSAKeyValueType();
|
||||||
dsaKeyValue.setP(Base64.encodeBytes(P).getBytes());
|
dsaKeyValue.setP(Base64.encodeBytes(P).getBytes(GeneralConstants.SAML_CHARSET));
|
||||||
dsaKeyValue.setQ(Base64.encodeBytes(Q).getBytes());
|
dsaKeyValue.setQ(Base64.encodeBytes(Q).getBytes(GeneralConstants.SAML_CHARSET));
|
||||||
dsaKeyValue.setG(Base64.encodeBytes(G).getBytes());
|
dsaKeyValue.setG(Base64.encodeBytes(G).getBytes(GeneralConstants.SAML_CHARSET));
|
||||||
dsaKeyValue.setY(Base64.encodeBytes(Y).getBytes());
|
dsaKeyValue.setY(Base64.encodeBytes(Y).getBytes(GeneralConstants.SAML_CHARSET));
|
||||||
return dsaKeyValue;
|
return dsaKeyValue;
|
||||||
}
|
}
|
||||||
throw logger.unsupportedType(key.toString());
|
throw logger.unsupportedType(key.toString());
|
||||||
|
|
|
@ -18,6 +18,7 @@ package org.keycloak.saml.processing.web.util;
|
||||||
|
|
||||||
import org.keycloak.saml.common.PicketLinkLogger;
|
import org.keycloak.saml.common.PicketLinkLogger;
|
||||||
import org.keycloak.saml.common.PicketLinkLoggerFactory;
|
import org.keycloak.saml.common.PicketLinkLoggerFactory;
|
||||||
|
import org.keycloak.saml.common.constants.GeneralConstants;
|
||||||
import org.keycloak.saml.common.util.Base64;
|
import org.keycloak.saml.common.util.Base64;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
|
@ -42,7 +43,7 @@ public class PostBindingUtil {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static String base64Encode(String stringToEncode) throws IOException {
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -79,7 +79,7 @@ public class RedirectBindingSignatureUtil {
|
||||||
String urlEncodedRelayState = null;
|
String urlEncodedRelayState = null;
|
||||||
|
|
||||||
if (isNotNull(relayState))
|
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,
|
byte[] sigValue = computeSignature(GeneralConstants.SAML_REQUEST_KEY, urlEncodedRequest, urlEncodedRelayState,
|
||||||
signingKey);
|
signingKey);
|
||||||
|
@ -113,7 +113,7 @@ public class RedirectBindingSignatureUtil {
|
||||||
|
|
||||||
String urlEncodedRelayState = null;
|
String urlEncodedRelayState = null;
|
||||||
if (isNotNull(relayState))
|
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,
|
byte[] sigValue = computeSignature(GeneralConstants.SAML_RESPONSE_KEY, urlEncodedResponse, urlEncodedRelayState,
|
||||||
signingKey);
|
signingKey);
|
||||||
|
@ -234,7 +234,7 @@ public class RedirectBindingSignatureUtil {
|
||||||
addParameter(sb, GeneralConstants.SAML_SIG_ALG_REQUEST_KEY,
|
addParameter(sb, GeneralConstants.SAML_SIG_ALG_REQUEST_KEY,
|
||||||
RedirectBindingSignatureUtil.getTokenValue(queryString, 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) {
|
private static boolean isRequestQueryString(String queryString) {
|
||||||
|
@ -257,7 +257,7 @@ public class RedirectBindingSignatureUtil {
|
||||||
String algo = signingKey.getAlgorithm();
|
String algo = signingKey.getAlgorithm();
|
||||||
String sigAlg = SignatureUtil.getXMLSignatureAlgorithmURI(algo);
|
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);
|
addParameter(sb, GeneralConstants.SAML_SIG_ALG_REQUEST_KEY, sigAlg);
|
||||||
|
|
||||||
|
@ -291,7 +291,7 @@ public class RedirectBindingSignatureUtil {
|
||||||
// SigAlg
|
// SigAlg
|
||||||
String sigAlg = SignatureUtil.getXMLSignatureAlgorithmURI(sigAlgo);
|
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);
|
addParameter(sb, GeneralConstants.SAML_SIG_ALG_REQUEST_KEY, sigAlg);
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
*/
|
*/
|
||||||
package org.keycloak.saml.processing.web.util;
|
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.Base64;
|
||||||
import org.keycloak.saml.common.util.StringUtil;
|
import org.keycloak.saml.common.util.StringUtil;
|
||||||
import org.keycloak.saml.processing.api.util.DeflateUtil;
|
import org.keycloak.saml.processing.api.util.DeflateUtil;
|
||||||
|
@ -43,7 +44,7 @@ public class RedirectBindingUtil {
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public static String urlEncode(String str) 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
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public static String urlDecode(String str) 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
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public static String deflateBase64URLEncode(String stringToEncode) throws IOException {
|
public static String deflateBase64URLEncode(String stringToEncode) throws IOException {
|
||||||
return deflateBase64URLEncode(stringToEncode.getBytes("UTF-8"));
|
return deflateBase64URLEncode(stringToEncode.getBytes(GeneralConstants.SAML_CHARSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
*/
|
*/
|
||||||
package org.keycloak.saml.processing.core.parsers.saml;
|
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 org.keycloak.dom.saml.v2.metadata.EntityDescriptorType;
|
||||||
|
|
||||||
import java.io.InputStream;
|
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.LogoutRequestType;
|
||||||
import org.keycloak.dom.saml.v2.protocol.ResponseType;
|
import org.keycloak.dom.saml.v2.protocol.ResponseType;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Scanner;
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
@ -108,6 +108,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
|
@Test
|
||||||
public void testSaml20PostLogoutRequest() throws Exception {
|
public void testSaml20PostLogoutRequest() throws Exception {
|
||||||
try (InputStream st = SAMLParserTest.class.getResourceAsStream("saml20-signed-logout-request.xml")) {
|
try (InputStream st = SAMLParserTest.class.getResourceAsStream("saml20-signed-logout-request.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>
|
|
@ -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>
|
Loading…
Reference in a new issue