Author: anil.saldhana(a)jboss.com
Date: 2011-06-23 18:25:12 -0400 (Thu, 23 Jun 2011)
New Revision: 1029
Added:
federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/parsers/saml/SAML11ResponseParser.java
federation/trunk/picketlink-fed-core/src/test/java/org/picketlink/test/identity/federation/core/parser/saml/SAML11ResponseParserTestCase.java
federation/trunk/picketlink-fed-core/src/test/resources/parser/saml1/saml1-response.xml
Modified:
federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/parsers/saml/SAMLParser.java
federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/parsers/saml/SAMLResponseParser.java
federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/saml/v1/SAML11Constants.java
federation/trunk/picketlink-fed-model/src/main/java/org/picketlink/identity/federation/saml/v1/protocol/SAML11ResponseType.java
Log:
more SAML11 parsing
Added:
federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/parsers/saml/SAML11ResponseParser.java
===================================================================
---
federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/parsers/saml/SAML11ResponseParser.java
(rev 0)
+++
federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/parsers/saml/SAML11ResponseParser.java 2011-06-23
22:25:12 UTC (rev 1029)
@@ -0,0 +1,185 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.picketlink.identity.federation.core.parsers.saml;
+
+import javax.xml.datatype.XMLGregorianCalendar;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.EndElement;
+import javax.xml.stream.events.StartElement;
+import javax.xml.stream.events.XMLEvent;
+
+import org.picketlink.identity.federation.core.exceptions.ParsingException;
+import org.picketlink.identity.federation.core.parsers.ParserNamespaceSupport;
+import org.picketlink.identity.federation.core.parsers.util.StaxParserUtil;
+import org.picketlink.identity.federation.core.saml.v1.SAML11Constants;
+import org.picketlink.identity.federation.core.saml.v2.constants.JBossSAMLConstants;
+import org.picketlink.identity.federation.core.saml.v2.util.XMLTimeUtil;
+import org.picketlink.identity.federation.saml.v1.assertion.SAML11AssertionType;
+import org.picketlink.identity.federation.saml.v1.protocol.SAML11ResponseType;
+import org.picketlink.identity.federation.saml.v1.protocol.SAML11StatusCodeType;
+import org.picketlink.identity.federation.saml.v1.protocol.SAML11StatusType;
+import org.w3c.dom.Element;
+
+/**
+ * Parse the SAML 11 Response
+ * @author Anil.Saldhana(a)redhat.com
+ * @since 23 June 2011
+ */
+public class SAML11ResponseParser implements ParserNamespaceSupport
+{
+ private final String RESPONSE = JBossSAMLConstants.RESPONSE.get();
+
+ /**
+ * @see {@link ParserNamespaceSupport#parse(XMLEventReader)}
+ */
+ public Object parse(XMLEventReader xmlEventReader) throws ParsingException
+ {
+ //Get the startelement
+ StartElement startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+ StaxParserUtil.validate(startElement, RESPONSE);
+
+ Attribute idAttr = startElement.getAttributeByName(new
QName("ResponseID"));
+ if (idAttr == null)
+ throw new RuntimeException("ID attribute is missing");
+ String id = StaxParserUtil.getAttributeValue(idAttr);
+
+ Attribute issueInstant = startElement.getAttributeByName(new
QName("IssueInstant"));
+ if (issueInstant == null)
+ throw new RuntimeException("IssueInstant attribute required in
Response");
+ XMLGregorianCalendar issueInstantVal =
XMLTimeUtil.parse(StaxParserUtil.getAttributeValue(issueInstant));
+
+ SAML11ResponseType response = new SAML11ResponseType(id, issueInstantVal);
+
+ while (xmlEventReader.hasNext())
+ {
+ //Let us peek at the next start element
+ startElement = StaxParserUtil.peekNextStartElement(xmlEventReader);
+ if (startElement == null)
+ break;
+ String elementName = StaxParserUtil.getStartElementName(startElement);
+ if (JBossSAMLConstants.SIGNATURE.get().equals(elementName))
+ {
+ Element sig = StaxParserUtil.getDOMElement(xmlEventReader);
+ response.setSignature(sig);
+ }
+ else if (JBossSAMLConstants.ASSERTION.get().equals(elementName))
+ {
+ SAML11AssertionParser assertionParser = new SAML11AssertionParser();
+ response.add((SAML11AssertionType) assertionParser.parse(xmlEventReader));
+ }
+ else if (JBossSAMLConstants.STATUS.get().equals(elementName))
+ {
+ response.setStatus(parseStatus(xmlEventReader));
+ }
+ else
+ throw new RuntimeException("Unknown tag=" + elementName +
"::location=" + startElement.getLocation());
+ }
+
+ return response;
+ }
+
+ /**
+ * Parse the status element
+ * @param xmlEventReader
+ * @return
+ * @throws ParsingException
+ */
+ protected SAML11StatusType parseStatus(XMLEventReader xmlEventReader) throws
ParsingException
+ {
+ //Get the Start Element
+ StartElement startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+ String STATUS = JBossSAMLConstants.STATUS.get();
+ StaxParserUtil.validate(startElement, STATUS);
+
+ SAML11StatusType status = new SAML11StatusType();
+
+ while (xmlEventReader.hasNext())
+ {
+ startElement = StaxParserUtil.peekNextStartElement(xmlEventReader);
+
+ if (startElement == null)
+ break;
+
+ QName startElementName = startElement.getName();
+ String elementTag = startElementName.getLocalPart();
+
+ SAML11StatusCodeType statusCode = new SAML11StatusCodeType();
+
+ if (JBossSAMLConstants.STATUS_CODE.get().equals(elementTag))
+ {
+ startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+ if (startElement == null)
+ break;
+ Attribute valueAttr = startElement.getAttributeByName(new
QName("Value"));
+ if (valueAttr != null)
+ {
+ statusCode.setValue(new
QName(StaxParserUtil.getAttributeValue(valueAttr)));
+ }
+ status.setStatusCode(statusCode);
+
+ //Peek at the next start element to see if it is status code
+ startElement = StaxParserUtil.peekNextStartElement(xmlEventReader);
+ elementTag = startElement.getName().getLocalPart();
+ if (JBossSAMLConstants.STATUS_CODE.get().equals(elementTag))
+ {
+ SAML11StatusCodeType subStatusCodeType = new SAML11StatusCodeType();
+ startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
+ Attribute subValueAttr = startElement.getAttributeByName(new
QName("Value"));
+ if (subValueAttr != null)
+ {
+ subStatusCodeType.setValue(new
QName(StaxParserUtil.getAttributeValue(subValueAttr)));
+ }
+ statusCode.setStatusCode(subStatusCodeType);
+
+ // Go to Status code end element.
+ EndElement endElement = StaxParserUtil.getNextEndElement(xmlEventReader);
+ StaxParserUtil.validate(endElement,
JBossSAMLConstants.STATUS_CODE.get());
+ continue;
+ }
+ }
+
+ //Get the next end element
+ XMLEvent xmlEvent = StaxParserUtil.peek(xmlEventReader);
+ if (xmlEvent instanceof EndElement)
+ {
+ EndElement endElement = StaxParserUtil.getNextEndElement(xmlEventReader);
+ if (StaxParserUtil.matches(endElement, STATUS))
+ break;
+ else
+ throw new RuntimeException("unknown end element:" +
StaxParserUtil.getEndElementName(endElement));
+ }
+ else
+ break;
+ }
+ return status;
+ }
+
+ /**
+ * @see {@link ParserNamespaceSupport#supports(QName)}
+ */
+ public boolean supports(QName qname)
+ {
+ return SAML11Constants.PROTOCOL_11_NSURI.equals(qname.getNamespaceURI()) &&
RESPONSE.equals(qname.getLocalPart());
+ }
+}
\ No newline at end of file
Modified:
federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/parsers/saml/SAMLParser.java
===================================================================
---
federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/parsers/saml/SAMLParser.java 2011-06-23
20:44:42 UTC (rev 1028)
+++
federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/parsers/saml/SAMLParser.java 2011-06-23
22:25:12 UTC (rev 1029)
@@ -63,7 +63,8 @@
String elementName = StaxParserUtil.getStartElementName(startElement);
- if (elementName.equalsIgnoreCase(JBossSAMLConstants.ASSERTION.get()))
+ if (elementName.equalsIgnoreCase(JBossSAMLConstants.ASSERTION.get())
+ || elementName.equals(JBossSAMLConstants.ENCRYPTED_ASSERTION.get()))
{
if (nsURI.equals(SAML11Constants.ASSERTION_11_NSURI))
{
@@ -97,7 +98,6 @@
SAMLResponseParser responseParser = new SAMLResponseParser();
return responseParser.parse(xmlEventReader);
}
-
else if (JBossSAMLURIConstants.PROTOCOL_NSURI.get().equals(nsURI)
&&
JBossSAMLConstants.REQUEST_ABSTRACT.get().equals(startElementName.getLocalPart()))
{
@@ -124,10 +124,11 @@
SAMLEntitiesDescriptorParser entityDescriptorParser = new
SAMLEntitiesDescriptorParser();
return entityDescriptorParser.parse(xmlEventReader);
}
- else if (JBossSAMLURIConstants.ASSERTION_NSURI.get().equals(nsURI))
+ else if (SAML11Constants.PROTOCOL_11_NSURI.equals(nsURI)
+ &&
JBossSAMLConstants.RESPONSE.get().equals(startElementName.getLocalPart()))
{
- SAMLAssertionParser assertionParser = new SAMLAssertionParser();
- return assertionParser.parse(xmlEventReader);
+ SAML11ResponseParser responseParser = new SAML11ResponseParser();
+ return responseParser.parse(xmlEventReader);
}
else
throw new RuntimeException("Unknown Tag:" + elementName +
"::location=" + startElement.getLocation());
Modified:
federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/parsers/saml/SAMLResponseParser.java
===================================================================
---
federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/parsers/saml/SAMLResponseParser.java 2011-06-23
20:44:42 UTC (rev 1028)
+++
federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/parsers/saml/SAMLResponseParser.java 2011-06-23
22:25:12 UTC (rev 1029)
@@ -76,8 +76,8 @@
}
else if (JBossSAMLConstants.SIGNATURE.get().equals(elementName))
{
- startElement = StaxParserUtil.getNextStartElement(xmlEventReader);
- StaxParserUtil.bypassElementBlock(xmlEventReader,
JBossSAMLConstants.SIGNATURE.get());
+ Element sig = StaxParserUtil.getDOMElement(xmlEventReader);
+ response.setSignature(sig);
}
else if (JBossSAMLConstants.ASSERTION.get().equals(elementName))
{
Modified:
federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/saml/v1/SAML11Constants.java
===================================================================
---
federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/saml/v1/SAML11Constants.java 2011-06-23
20:44:42 UTC (rev 1028)
+++
federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/saml/v1/SAML11Constants.java 2011-06-23
22:25:12 UTC (rev 1029)
@@ -68,5 +68,7 @@
String NAMESPACE = "Namespace";
+ String PROTOCOL_11_NSURI = "urn:oasis:names:tc:SAML:1.0:protocol";
+
String RESOURCE = "Resource";
}
\ No newline at end of file
Added:
federation/trunk/picketlink-fed-core/src/test/java/org/picketlink/test/identity/federation/core/parser/saml/SAML11ResponseParserTestCase.java
===================================================================
---
federation/trunk/picketlink-fed-core/src/test/java/org/picketlink/test/identity/federation/core/parser/saml/SAML11ResponseParserTestCase.java
(rev 0)
+++
federation/trunk/picketlink-fed-core/src/test/java/org/picketlink/test/identity/federation/core/parser/saml/SAML11ResponseParserTestCase.java 2011-06-23
22:25:12 UTC (rev 1029)
@@ -0,0 +1,72 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.picketlink.test.identity.federation.core.parser.saml;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.InputStream;
+import java.util.List;
+
+import org.junit.Test;
+import org.picketlink.identity.federation.core.parsers.saml.SAML11ResponseParser;
+import org.picketlink.identity.federation.core.parsers.saml.SAMLParser;
+import org.picketlink.identity.federation.core.saml.v2.util.XMLTimeUtil;
+import org.picketlink.identity.federation.saml.v1.assertion.SAML11AssertionType;
+import org.picketlink.identity.federation.saml.v1.protocol.SAML11ResponseType;
+import org.picketlink.identity.federation.saml.v1.protocol.SAML11StatusCodeType;
+import org.picketlink.identity.federation.saml.v1.protocol.SAML11StatusType;
+
+/**
+ * Unit Test the {@link SAML11ResponseParser}
+ * @author Anil.Saldhana(a)redhat.com
+ * @since Jun 23, 2011
+ */
+public class SAML11ResponseParserTestCase
+{
+ @Test
+ public void testSAML11Response() throws Exception
+ {
+ ClassLoader tcl = Thread.currentThread().getContextClassLoader();
+ InputStream configStream =
tcl.getResourceAsStream("parser/saml1/saml1-response.xml");
+
+ SAMLParser parser = new SAMLParser();
+ SAML11ResponseType response = (SAML11ResponseType) parser.parse(configStream);
+ assertNotNull(response);
+
+ assertEquals(1, response.getMajorVersion());
+ assertEquals(1, response.getMinorVersion());
+ assertEquals("_P1YaA+Q/wSM/t/8E3R8rNhcpPTM=", response.getID());
+ assertEquals(XMLTimeUtil.parse("2002-06-19T17:05:37.795Z"),
response.getIssueInstant());
+
+ assertNotNull(response.getSignature());
+
+ SAML11StatusType status = response.getStatus();
+ SAML11StatusCodeType statusCode = status.getStatusCode();
+ assertEquals("samlp:Success", statusCode.getValue().toString());
+
+ List<SAML11AssertionType> assertions = response.get();
+ assertEquals(1, assertions.size());
+ SAML11AssertionType assertion = assertions.get(0);
+ assertEquals("buGxcG4gILg5NlocyLccDz6iXrUa", assertion.getID());
+ }
+}
\ No newline at end of file
Added:
federation/trunk/picketlink-fed-core/src/test/resources/parser/saml1/saml1-response.xml
===================================================================
---
federation/trunk/picketlink-fed-core/src/test/resources/parser/saml1/saml1-response.xml
(rev 0)
+++
federation/trunk/picketlink-fed-core/src/test/resources/parser/saml1/saml1-response.xml 2011-06-23
22:25:12 UTC (rev 1029)
@@ -0,0 +1,55 @@
+<samlp:Response
+ xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol"
+ MajorVersion="1" MinorVersion="1"
+ ResponseID="_P1YaA+Q/wSM/t/8E3R8rNhcpPTM="
+ IssueInstant="2002-06-19T17:05:37.795Z">
+ <Signature
xmlns="http://www.w3.org/2000/09/xmldsig#">
+ <SignedInfo>
+ <CanonicalizationMethod
Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
+ <SignatureMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"
/>
+ <Reference URI="#s69f7e258e30da2b9b9f5799d4eb0c548782432bf">
+ <Transforms>
+ <Transform
Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
+ <Transform
Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
+ </Transforms>
+ <DigestMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
+ <DigestValue>zdCY/1iqOMUJq/RvxsaDPWM4+7c=</DigestValue>
+ </Reference>
+ </SignedInfo>
+ <SignatureValue>ApcX/Ddfsfdslkfd</SignatureValue>
+ <KeyInfo>
+ <X509Data>
+ <X509Certificate>MIICmjdfdflkfdslfaf;sjdposafhpofhpowfowqpowqfow
+ </X509Certificate>
+ </X509Data>
+ </KeyInfo>
+ </Signature>
+ <samlp:Status>
+ <samlp:StatusCode Value="samlp:Success"/>
+ </samlp:Status>
+ <saml:Assertion
+ xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion"
+ MajorVersion="1" MinorVersion="1"
+ AssertionID="buGxcG4gILg5NlocyLccDz6iXrUa"
+
Issuer="https://idp.example.org/saml"
+ IssueInstant="2002-06-19T17:05:37.795Z">
+ <saml:Conditions
+ NotBefore="2002-06-19T17:00:37.795Z"
+ NotOnOrAfter="2002-06-19T17:10:37.795Z"/>
+ <saml:AuthenticationStatement
+ AuthenticationMethod="urn:oasis:names:tc:SAML:1.0:am:password"
+ AuthenticationInstant="2002-06-19T17:05:17.706Z">
+ <saml:Subject>
+ <saml:NameIdentifier
+ Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">
+ user(a)idp.example.org
+ </saml:NameIdentifier>
+ <saml:SubjectConfirmation>
+ <saml:ConfirmationMethod>
+ urn:oasis:names:tc:SAML:1.0:cm:bearer
+ </saml:ConfirmationMethod>
+ </saml:SubjectConfirmation>
+ </saml:Subject>
+ </saml:AuthenticationStatement>
+ </saml:Assertion>
+ </samlp:Response>
\ No newline at end of file
Modified:
federation/trunk/picketlink-fed-model/src/main/java/org/picketlink/identity/federation/saml/v1/protocol/SAML11ResponseType.java
===================================================================
---
federation/trunk/picketlink-fed-model/src/main/java/org/picketlink/identity/federation/saml/v1/protocol/SAML11ResponseType.java 2011-06-23
20:44:42 UTC (rev 1028)
+++
federation/trunk/picketlink-fed-model/src/main/java/org/picketlink/identity/federation/saml/v1/protocol/SAML11ResponseType.java 2011-06-23
22:25:12 UTC (rev 1029)
@@ -27,7 +27,6 @@
import javax.xml.datatype.XMLGregorianCalendar;
-import org.picketlink.identity.federation.saml.common.CommonResponseType;
import org.picketlink.identity.federation.saml.v1.assertion.SAML11AssertionType;
/**
@@ -46,7 +45,7 @@
* @author Anil.Saldhana(a)redhat.com
* @since Jun 22, 2011
*/
-public class SAML11ResponseType extends CommonResponseType
+public class SAML11ResponseType extends SAML11ResponseAbstractType
{
private static final long serialVersionUID = 1L;