comparison gwt-client/src/main/java/org/dive4elements/river/client/server/auth/was/Response.java @ 9497:d6d5ca6d4af0

Enabled logging of saml-group-name in log-ing logfile. Some cleanup/refaktoring.
author gernotbelger
date Thu, 27 Sep 2018 17:40:39 +0200
parents 5e38e2924c07
children
comparison
equal deleted inserted replaced
9486:ce13a2f07290 9497:d6d5ca6d4af0
12 import java.io.InputStream; 12 import java.io.InputStream;
13 import java.io.StringBufferInputStream; 13 import java.io.StringBufferInputStream;
14 import java.util.List; 14 import java.util.List;
15 15
16 import org.apache.commons.codec.binary.Base64InputStream; 16 import org.apache.commons.codec.binary.Base64InputStream;
17
18 import org.apache.http.HttpEntity; 17 import org.apache.http.HttpEntity;
19 import org.apache.http.util.EntityUtils; 18 import org.apache.http.util.EntityUtils;
20
21 import org.apache.log4j.Logger; 19 import org.apache.log4j.Logger;
22
23 import org.w3c.dom.Document;
24 import org.w3c.dom.Element;
25
26 import org.dive4elements.artifacts.httpclient.utils.XMLUtils; 20 import org.dive4elements.artifacts.httpclient.utils.XMLUtils;
27 import org.dive4elements.river.client.server.auth.Authentication; 21 import org.dive4elements.river.client.server.auth.Authentication;
28 import org.dive4elements.river.client.server.auth.AuthenticationException; 22 import org.dive4elements.river.client.server.auth.AuthenticationException;
23 import org.dive4elements.river.client.server.auth.DefaultUser;
24 import org.dive4elements.river.client.server.auth.User;
29 import org.dive4elements.river.client.server.auth.saml.Assertion; 25 import org.dive4elements.river.client.server.auth.saml.Assertion;
26 import org.dive4elements.river.client.server.auth.saml.TicketValidator;
30 import org.dive4elements.river.client.server.auth.saml.XPathUtils; 27 import org.dive4elements.river.client.server.auth.saml.XPathUtils;
31 import org.dive4elements.river.client.server.auth.saml.TicketValidator;
32 import org.dive4elements.river.client.server.auth.saml.User;
33
34 import org.dive4elements.river.client.server.features.Features; 28 import org.dive4elements.river.client.server.features.Features;
35 29 import org.w3c.dom.Document;
30 import org.w3c.dom.Element;
36 31
37 public class Response implements Authentication { 32 public class Response implements Authentication {
38 33
39 private static Logger log = Logger.getLogger(Response.class); 34 private static Logger log = Logger.getLogger(Response.class);
40 35
41 private Element root; 36 private final Element root;
42 private String samlTicketXML; 37 private final String samlTicketXML;
43 private Assertion assertion; 38 private Assertion assertion;
44 private String username; 39 private final String password;
45 private String password; 40 private final Features features;
46 private Features features; 41 private final String trustedKeyFile;
47 private String trustedKeyFile; 42 private final String timeEpsilon;
48 private String timeEpsilon;
49 43
50 44 public Response(final HttpEntity entity, final String password, final Features features, final String trustedKeyFile,
51 public Response(HttpEntity entity, String username, String password, 45 final String timeEpsilon) throws AuthenticationException, IOException {
52 Features features, String trustedKeyFile, String timeEpsilon)
53 throws AuthenticationException, IOException {
54 46
55 if (entity == null) { 47 if (entity == null) {
56 throw new ServiceException("Invalid response"); 48 throw new ServiceException("Invalid response");
57 } 49 }
58 50
59 String contenttype = entity.getContentType().getValue(); 51 final String contenttype = entity.getContentType().getValue();
60 String samlTicketXML = EntityUtils.toString(entity); 52 final String samlTicketXML = EntityUtils.toString(entity);
61 53
62 InputStream in = new StringBufferInputStream(samlTicketXML); 54 InputStream in = new StringBufferInputStream(samlTicketXML);
63 55
64 if (!contenttype.equals("application/vnd.ogc.se_xml")) { 56 if (!contenttype.equals("application/vnd.ogc.se_xml")) {
65 // XXX: Assume base64 encoded content. 57 // XXX: Assume base64 encoded content.
66 in = new Base64InputStream(in); 58 in = new Base64InputStream(in);
67 } 59 }
68 60
69 Document doc = XMLUtils.readDocument(in); 61 final Document doc = XMLUtils.readDocument(in);
70 Element root = doc.getDocumentElement(); 62 final Element root = doc.getDocumentElement();
71 String rname = root.getTagName(); 63 final String rname = root.getTagName();
72 64
73 if (rname != null && rname.equals("ServiceExceptionReport")) { 65 if (rname != null && rname.equals("ServiceExceptionReport"))
74 throw new ServiceException(XPathUtils.xpathString(root, 66 throw new ServiceException(XPathUtils.xpathString(root, "ServiceException"));
75 "ServiceException"));
76 }
77 67
78 this.samlTicketXML = samlTicketXML; 68 this.samlTicketXML = samlTicketXML;
79 this.root = root; 69 this.root = root;
80 this.username = username;
81 this.password = password; 70 this.password = password;
82 this.features = features; 71 this.features = features;
83 this.trustedKeyFile = trustedKeyFile; 72 this.trustedKeyFile = trustedKeyFile;
84 this.timeEpsilon = timeEpsilon; 73 this.timeEpsilon = timeEpsilon;
85 } 74 }
86 75
87 @Override 76 @Override
88 public boolean isSuccess() { 77 public boolean isSuccess() {
89 String status = getStatus(); 78 final String status = getStatus();
90 return status != null && status.equals("samlp:Success"); 79 return status != null && status.equals("samlp:Success");
91 } 80 }
92 81
93 public String getStatus() { 82 private String getStatus() {
94 return XPathUtils.xpathString(this.root, 83 return XPathUtils.xpathString(this.root, "./samlp:Status/samlp:StatusCode/@Value");
95 "./samlp:Status/samlp:StatusCode/@Value");
96 } 84 }
97 85
98 86 private Assertion getAssertion() {
99 public Assertion getAssertion() {
100 if (this.assertion == null && this.root != null) { 87 if (this.assertion == null && this.root != null) {
101 try { 88 try {
102 int timeEps = Integer.parseInt(this.timeEpsilon); 89 final int timeEps = Integer.parseInt(this.timeEpsilon);
103 TicketValidator validator = 90 final TicketValidator validator = new TicketValidator(this.trustedKeyFile, timeEps);
104 new TicketValidator(this.trustedKeyFile, timeEps);
105 this.assertion = validator.checkTicket(this.root); 91 this.assertion = validator.checkTicket(this.root);
106 } 92 }
107 catch (Exception e) { 93 catch (final Exception e) {
108 log.error(e.getLocalizedMessage(), e); 94 log.error(e.getLocalizedMessage(), e);
109 } 95 }
110 } 96 }
111 return this.assertion; 97 return this.assertion;
112 } 98 }
113 99
114 @Override 100 @Override
115 public User getUser() throws AuthenticationException { 101 public User getUser() throws AuthenticationException {
116 Assertion assertion = this.getAssertion(); 102 final Assertion assertion = this.getAssertion();
117 if (assertion == null) { 103 if (assertion == null)
118 throw new AuthenticationException( 104 throw new AuthenticationException("Response doesn't contain an assertion");
119 "Response doesn't contain an assertion"); 105
120 } 106 final DefaultUser user = createUser(this.password, this.samlTicketXML, assertion, this.features);
121 List<String> features = this.features.getFeatures( 107
122 this.assertion.getRoles()); 108 log.debug("User " + user.getName() + " with features " + user.getAllowedFeatures() + " successfully authenticated.");
123 log.debug("User " + this.username + " with features " + features + 109
124 " successfully authenticated."); 110 return user;
125 return new User(assertion, this.samlTicketXML, features, this.password); 111 }
112
113 public static DefaultUser createUser(final String password, final String samlTicketXML, final Assertion assertion, final Features features) {
114 final List<String> roles = assertion.getRoles();
115
116 final List<String> allowedFeatures = features.getFeatures(roles);
117
118 // We could check the validity dates of the assertion here, but
119 // when using this for Single-Sign-On this would lead to the
120 // code in GGInAFilter to re-authenticate with the password
121 // stored in the User object, which isn't known in the case of
122 // Single-Sign-On.
123 final boolean expired = false;
124
125 final String username = assertion.getNameID();
126 final String userGroup = assertion.getGroupName();
127
128 return new DefaultUser(username, password, samlTicketXML, expired, roles, allowedFeatures, userGroup);
126 } 129 }
127 } 130 }
128 // vim: set si et fileencoding=utf-8 ts=4 sw=4 tw=80:

http://dive4elements.wald.intevation.org