annotate gwt-client/src/main/java/org/dive4elements/river/client/server/auth/saml/TicketValidator.java @ 5948:d7b9b3e3c61a

Make instantiation of saml.User easier. Most of the parameters of the constructor can be taken from the Assertion object, so there's no reason to pass them separately. Also, trying to check the validity dates isn't useful for the single sign on case. See comments in the hasExpired method.
author Bernhard Herzog <bh@intevation.de>
date Wed, 08 May 2013 17:56:14 +0200
parents c1806821860b
children 0a0b4bfdf372
rev   line source
5941
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
1 /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt f�r Gew�sserkunde
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
2 * Software engineering by Intevation GmbH
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
3 *
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
4 * This file is Free Software under the GNU AGPL (>=v3)
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
5 * and comes with ABSOLUTELY NO WARRANTY! Check out the
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
6 * documentation coming with Dive4Elements River for details.
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
7 */
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
8
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
9 package org.dive4elements.river.client.server.auth.saml;
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
10
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
11 import java.io.FileInputStream;
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
12 import java.io.IOException;
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
13 import java.security.Key;
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
14 import java.util.Iterator;
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
15 import java.util.Date;
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
16 import javax.security.cert.X509Certificate;
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
17 import javax.security.cert.CertificateException;
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
18 import javax.xml.crypto.Data;
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
19 import javax.xml.crypto.NodeSetData;
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
20 import javax.xml.crypto.dsig.Reference;
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
21 import javax.xml.crypto.dsig.XMLSignature;
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
22 import javax.xml.crypto.dsig.XMLSignatureFactory;
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
23 import javax.xml.crypto.dsig.dom.DOMValidateContext;
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
24
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
25 import org.apache.log4j.Logger;
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
26
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
27 import org.w3c.dom.Element;
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
28 import org.w3c.dom.Node;
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
29 import org.w3c.dom.NodeList;
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
30
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
31 /**
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
32 * Validator for SAML tickets.
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
33 */
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
34 public class TicketValidator {
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
35
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
36 /**
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
37 * The logger used by the TicketValidator instances.
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
38 */
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
39 private static Logger logger = Logger.getLogger(TicketValidator.class);
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
40
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
41 /**
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
42 * The trusted Key for signature checks.
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
43 */
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
44 private Key trustedKey;
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
45
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
46 /**
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
47 * Creates a new TicketValidator from a trusted key.
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
48 * @param trustedKey The trusted key for the signature checks.
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
49 */
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
50 public TicketValidator(Key trustedKey) {
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
51 this.trustedKey = trustedKey;
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
52 }
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
53
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
54 /**
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
55 * Creates a new TicketValidator, loading the trusted key from a
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
56 * file.
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
57 * @param filename The filename of the X509 certificate containing
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
58 * the trusted public key.
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
59 */
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
60 public TicketValidator(String filename) throws IOException,
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
61 CertificateException {
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
62 this.trustedKey = loadKey(filename);
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
63 }
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
64
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
65 /**
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
66 * Loads the public key from a file containing an X509 certificate.
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
67 */
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
68 private Key loadKey(String filename) throws IOException,
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
69 CertificateException {
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
70 X509Certificate cert = X509Certificate.getInstance(
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
71 new FileInputStream(filename));
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
72 cert.checkValidity(new Date());
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
73 return cert.getPublicKey();
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
74 }
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
75
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
76
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
77 /**
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
78 * Check the ticket represented by the given DOM element.
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
79 * @param root the DOM element under which the signature can be
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
80 * found.
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
81 * @return The assertion element from the signed data.
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
82 */
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
83 public Assertion checkTicket(Element root) throws Exception {
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
84 markAssertionIdAttributes(root);
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
85
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
86 Node signode = XPathUtils.xpathNode(root, ".//ds:Signature");
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
87
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
88 DOMValidateContext context = new DOMValidateContext(this.trustedKey,
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
89 signode);
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
90 context.setProperty("javax.xml.crypto.dsig.cacheReference", true);
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
91
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
92 XMLSignatureFactory factory = XMLSignatureFactory.getInstance("DOM");
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
93 XMLSignature signature = factory.unmarshalXMLSignature(context);
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
94 if (!signature.validate(context)) {
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
95 logger.error("Signature of SAML ticket could not be validated.");
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
96 return null;
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
97 }
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
98
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
99 Element assertionElement = extractAssertion(signature, context);
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
100 if (assertionElement == null) {
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
101 logger.error("Could not extract assertion from signed content.");
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
102 return null;
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
103 }
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
104
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
105 Assertion assertion = new Assertion(assertionElement);
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
106 if (!assertion.isValidNow()) {
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
107 logger.error("Ticket is not valid now"
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
108 + " (NotBefore: " + assertion.getFrom()
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
109 + ", NotOnOrAfter: " + assertion.getUntil());
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
110 return null;
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
111 }
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
112
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
113 return assertion;
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
114 }
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
115
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
116 /**
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
117 * Mark the AssertionID attribute of SAML Assertion elements as ID
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
118 * attribute, so that the signature checker can resolve the
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
119 * references properly and find the signed data.
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
120 */
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
121 private void markAssertionIdAttributes(Element root) {
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
122 NodeList nodes = XPathUtils.xpathNodeList(root, "saml:Assertion");
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
123 for (int i = 0; i < nodes.getLength(); i++) {
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
124 Element el = (Element)nodes.item(i);
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
125 el.setIdAttribute("AssertionID", true);
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
126 }
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
127 }
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
128
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
129 private Element extractAssertion(XMLSignature sig,
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
130 DOMValidateContext context) {
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
131 for (Object obj: sig.getSignedInfo().getReferences()) {
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
132 Data data = ((Reference)obj).getDereferencedData();
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
133 if (data instanceof NodeSetData) {
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
134 Iterator i = ((NodeSetData)data).iterator();
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
135 for (int k = 0; i.hasNext(); k++) {
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
136 Object node = i.next();
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
137 if (node instanceof Element) {
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
138 Element el = (Element)node;
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
139 if (el.getTagName().equals("Assertion"))
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
140 return el;
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
141 }
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
142 }
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
143 }
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
144 }
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
145
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
146 return null;
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
147 }
c1806821860b Add SAML ticket validator classes.
Bernhard Herzog <bh@intevation.de>
parents:
diff changeset
148 }

http://dive4elements.wald.intevation.org