1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 package dk.sosi.seal.modelbuilders;
30
31 import dk.sosi.seal.model.IDCard;
32 import dk.sosi.seal.model.IdentityTokenRequest;
33 import dk.sosi.seal.model.SchemaUtil;
34 import dk.sosi.seal.model.SignatureUtil;
35 import dk.sosi.seal.model.constants.*;
36 import dk.sosi.seal.pki.Federation;
37 import dk.sosi.seal.xml.XmlUtil;
38 import org.w3c.dom.Document;
39 import org.w3c.dom.Element;
40 import org.w3c.dom.Node;
41 import org.xml.sax.SAXException;
42
43 import javax.xml.transform.dom.DOMSource;
44 import javax.xml.validation.Schema;
45 import javax.xml.validation.Validator;
46 import java.io.IOException;
47
48
49
50
51
52
53
54 public class IdentityTokenRequestModelBuilder {
55
56 private final Federation federation;
57
58
59
60
61
62
63
64 public IdentityTokenRequestModelBuilder(Federation federation) {
65 this.federation = federation;
66 }
67
68 private static Schema schema;
69
70
71
72
73
74
75
76
77
78
79
80
81
82 public IdentityTokenRequest buildModel(Document document) {
83
84 schemaValidate(document);
85
86 final Element header = XmlUtil.getFirstChildElementNS(document.getDocumentElement(), NameSpaces.SOAP_SCHEMA, SOAPTags.HEADER_UNPREFIXED);
87 final Element messageID = XmlUtil.getFirstChildElementNS(header, NameSpaces.WSA_1_0_SCHEMA, WSATags.MESSAGE_ID);
88
89 final Element body = XmlUtil.getFirstChildElementNS(document.getDocumentElement(), NameSpaces.SOAP_SCHEMA, SOAPTags.BODY_UNPREFIXED);
90 final Element requestSecurityToken = XmlUtil.getFirstChildElementNS(body, NameSpaces.WST_1_3_SCHEMA, WSTrustTags.REQUEST_SECURITY_TOKEN);
91 final String context = requestSecurityToken.getAttribute(WSTrustAttributes.CONTEXT);
92 final Element appliesTo = XmlUtil.getFirstChildElementNS(requestSecurityToken, NameSpaces.WSP_SCHEMA, WSPTags.APPLIES_TO);
93 final Element address = (Element) appliesTo.getFirstChild().getFirstChild();
94
95 Element assertion;
96 final Element security = XmlUtil.getFirstChildElementNS(header, NameSpaces.WSSE_SCHEMA, WSSETags.SECURITY);
97 if (security != null) {
98
99 assertion = (Element) security.getFirstChild();
100 } else {
101
102 final Element actAs = XmlUtil.getFirstChildElementNS(requestSecurityToken, NameSpaces.WST_1_4_SCHEMA, WSTrustTags.WST_1_4_ACT_AS);
103 assertion = XmlUtil.getFirstChildElementNS(actAs, NameSpaces.SAML2ASSERTION_SCHEMA, SAMLTags.ASSERTION);
104 if (assertion == null) {
105 throw new ModelBuildException("Expected idCard under wst14:ActAs");
106 }
107 }
108 final IDCard idCard = new IDCardModelBuilder().buildModel(assertion);
109 final Node signature = assertion.getElementsByTagNameNS(NameSpaces.DSIG_SCHEMA, DSTags.SIGNATURE).item(0);
110 if( ! SignatureUtil.validate(signature, federation, null, true)) {
111 throw new ModelBuildException("Signature on IdCard could not be validated");
112 }
113
114 return new IdentityTokenRequest(idCard, messageID.getTextContent(), address.getTextContent(), context);
115 }
116
117 private void schemaValidate(Document envelope) {
118 try {
119 final Validator validator = getSchema().newValidator();
120 validator.validate(new DOMSource(envelope));
121 } catch (SAXException e) {
122 throw new ModelBuildException("Error validating IdentityTokenRequest", e);
123 } catch (IOException e) {
124 throw new ModelBuildException("Error validating IdentityTokenRequest", e);
125 }
126
127 }
128
129 private static synchronized Schema getSchema() throws SAXException {
130 if (schema == null) {
131 schema = SchemaUtil.loadSchema("/idwsh/idtreq/soap.xsd");
132 }
133 return schema;
134 }
135
136 }