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 uk.ac.rdg.resc.jstyx.server;
30
31 import javax.net.ssl.SSLContext;
32 import java.util.Iterator;
33
34 import org.apache.log4j.Logger;
35
36 import org.dom4j.io.SAXReader;
37 import org.dom4j.Document;
38 import org.dom4j.DocumentException;
39 import org.dom4j.Node;
40
41 import uk.ac.rdg.resc.jstyx.StyxUtils;
42
43 /***
44 * Describes security information for a Styx server. This is used for finding
45 * valid users and groups and whether or not anonymous logins are allowed.
46 *
47 * @author Jon Blower
48 * $Revision: 604 $
49 * $Date: 2006-03-21 14:58:42 +0000 (Tue, 21 Mar 2006) $
50 * $Log$
51 * Revision 1.3 2006/03/21 14:58:42 jonblower
52 * Implemented clear-text password-based authentication and did some simple tests
53 *
54 * Revision 1.2 2006/03/21 09:06:15 jonblower
55 * Still implementing authentication
56 *
57 * Revision 1.1 2006/03/20 17:51:50 jonblower
58 * Adding authentication to base JStyx system
59 *
60 */
61 public class StyxSecurityContext
62 {
63 private static final Logger log = Logger.getLogger(StyxSecurityContext.class);
64
65 private String securityFile;
66 private boolean allowAnonymousLogin;
67 private boolean supportAuthentication;
68 private SSLContext sslContext;
69
70 /***
71 * Creates a security context in which anonymous logins are allowed,
72 * SSL is not used and authentication is not supported
73 */
74 public StyxSecurityContext()
75 {
76 this.allowAnonymousLogin = true;
77 this.supportAuthentication = false;
78 this.sslContext = null;
79 }
80
81 /***
82 * Creates a new StyxSecurityContext from a configuration file
83 * @param securityFile XML File from which security information is to be read.
84 * If this is null, access to the server will be anonymous and unsecured.
85 * @throws StyxSecurityException if the security config file could not be read
86 */
87 public StyxSecurityContext(String securityFile) throws StyxSecurityException
88 {
89 try
90 {
91 this.securityFile = securityFile;
92 if (this.securityFile == null)
93 {
94 throw new IllegalArgumentException("securityFile cannot be null");
95 }
96
97 SAXReader reader = new SAXReader(true);
98 Document doc = reader.read(securityFile);
99 Node serverNode = doc.selectSingleNode("security/server");
100 this.allowAnonymousLogin =
101 serverNode.valueOf("@allowAnonymousLogin").equalsIgnoreCase("true");
102 this.supportAuthentication = true;
103 if (serverNode.valueOf("useSSL").equalsIgnoreCase("true"))
104 {
105
106 }
107 }
108 catch (DocumentException de)
109 {
110 throw new StyxSecurityException("Error reading security config file "
111 + securityFile + ": " + de.getMessage());
112 }
113 }
114
115 /***
116 * @return true if this security context allows users to login anonymously
117 */
118 public boolean allowsAnonymousLogin()
119 {
120 return this.allowAnonymousLogin;
121 }
122
123 /***
124 * @return true if this server supports authentication
125 */
126 public boolean supportsAuthentication()
127 {
128 return this.supportAuthentication;
129 }
130
131 /***
132 * @return the SSLContext for this server, or null if we are not using SSL
133 */
134 public SSLContext getSSLContext()
135 {
136 return this.sslContext;
137 }
138
139 /***
140 * @return a User object for the anonymous user
141 */
142 public User getAnonymousUser()
143 {
144 return new User(this, StyxUtils.ANONYMOUS_USER, "", "Anonymous User");
145 }
146
147 /***
148 * @return an object describing the user with the given username
149 * @throws StyxSecurityException if a user with the given name does not
150 * exist in this security context or if this server does not support authentication
151 * or if there was an error finding the user's details
152 */
153 public User getUser(String username) throws StyxSecurityException
154 {
155 if (this.supportAuthentication)
156 {
157 try
158 {
159 SAXReader reader = new SAXReader(true);
160 Document doc = reader.read(securityFile);
161 Node userNode =
162 doc.selectSingleNode("security/users/user[@name='" +
163 username + "']");
164 if (userNode == null)
165 {
166 throw new StyxSecurityException("User " + username + " not found");
167 }
168 String password = userNode.selectSingleNode("password").getText();
169 String fullName = userNode.selectSingleNode("fullName").getText();
170 return new User(this, username, password, fullName);
171 }
172 catch(DocumentException de)
173 {
174 throw new StyxSecurityException("Error reading security config file "
175 + securityFile + ": " + de.getMessage());
176 }
177 }
178 else
179 {
180 throw new StyxSecurityException("Server does not support authentication");
181 }
182 }
183
184 /***
185 * @return true if the given user is a member of the given group. If the
186 * group is the default group (StyxUtils.DEFAULT_GROUP) this will return true
187 * as all users are members of this group. If the user is the anonymous user
188 * (StyxUtils.ANONYMOUS_USER) this will return false unless the group is the
189 * default group.
190 */
191 public boolean isMember(String username, String group)
192 {
193 log.debug("Checking to see if " + username + " is a member of " + group);
194 if (group.equals(StyxUtils.DEFAULT_GROUP))
195 {
196
197 return true;
198 }
199 else if (username.equals(StyxUtils.ANONYMOUS_USER))
200 {
201
202 return false;
203 }
204 else
205 {
206 try
207 {
208
209 SAXReader reader = new SAXReader(true);
210 Document doc = reader.read(this.securityFile);
211 Node groupNode =
212 doc.selectSingleNode("security/groups/group[@name='" +
213 group + "']");
214 if (groupNode == null)
215 {
216 log.debug("Group " + group + " not found");
217 return false;
218 }
219 else
220 {
221 Iterator usernames = groupNode.selectNodes("username").iterator();
222 while (usernames.hasNext())
223 {
224 Node usernameNode = (Node)usernames.next();
225 if (usernameNode.getText().trim().equals(username))
226 {
227
228 return true;
229 }
230 }
231
232 return false;
233 }
234 }
235 catch(DocumentException de)
236 {
237
238 log.error("Error occurred getting details for group " + group
239 + " from " + this.securityFile);
240 return false;
241 }
242 }
243 }
244
245 /***
246 * Simple test routine
247 */
248 public static void main(String[] args) throws Exception
249 {
250 StyxSecurityContext context = new StyxSecurityContext("E://Jon's Documents" +
251 "//work//java//JStyx//core//conf//styxSecurity.xml");
252 User jdb = context.getUser("jdb");
253 }
254 }