2 // ========================================================================
3 // Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
4 // ------------------------------------------------------------------------
5 // All rights reserved. This program and the accompanying materials
6 // are made available under the terms of the Eclipse Public License v1.0
7 // and Apache License v2.0 which accompanies this distribution.
9 // The Eclipse Public License is available at
10 // http://www.eclipse.org/legal/epl-v10.html
12 // The Apache License v2.0 is available at
13 // http://www.opensource.org/licenses/apache2.0.php
15 // You may elect to redistribute this code under either of these licenses.
16 // ========================================================================
20 package org.eclipse.jetty.security;
22 import java.io.IOException;
23 import java.io.Serializable;
24 import java.security.Principal;
26 import java.util.concurrent.ConcurrentHashMap;
27 import java.util.concurrent.ConcurrentMap;
29 import javax.security.auth.Subject;
31 import org.eclipse.jetty.server.UserIdentity;
32 import org.eclipse.jetty.util.component.AbstractLifeCycle;
33 import org.eclipse.jetty.util.log.Log;
34 import org.eclipse.jetty.util.log.Logger;
35 import org.eclipse.jetty.util.security.Credential;
39 /* ------------------------------------------------------------ */
41 * A login service that keeps UserIdentities in a concurrent map
42 * either as the source or a cache of the users.
45 public abstract class MappedLoginService extends AbstractLifeCycle implements LoginService
47 private static final Logger LOG = Log.getLogger(MappedLoginService.class);
49 protected IdentityService _identityService=new DefaultIdentityService();
50 protected String _name;
51 protected final ConcurrentMap<String, UserIdentity> _users=new ConcurrentHashMap<String, UserIdentity>();
53 /* ------------------------------------------------------------ */
54 protected MappedLoginService()
58 /* ------------------------------------------------------------ */
62 public String getName()
67 /* ------------------------------------------------------------ */
68 /** Get the identityService.
69 * @return the identityService
71 public IdentityService getIdentityService()
73 return _identityService;
76 /* ------------------------------------------------------------ */
80 public ConcurrentMap<String, UserIdentity> getUsers()
85 /* ------------------------------------------------------------ */
86 /** Set the identityService.
87 * @param identityService the identityService to set
89 public void setIdentityService(IdentityService identityService)
92 throw new IllegalStateException("Running");
93 _identityService = identityService;
96 /* ------------------------------------------------------------ */
98 * @param name the name to set
100 public void setName(String name)
103 throw new IllegalStateException("Running");
107 /* ------------------------------------------------------------ */
109 * @param users the users to set
111 public void setUsers(Map<String, UserIdentity> users)
114 throw new IllegalStateException("Running");
116 _users.putAll(users);
119 /* ------------------------------------------------------------ */
121 * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
124 protected void doStart() throws Exception
130 /* ------------------------------------------------------------ */
132 protected void doStop() throws Exception
137 /* ------------------------------------------------------------ */
138 public void logout(UserIdentity identity)
140 LOG.debug("logout {}",identity);
143 /* ------------------------------------------------------------ */
145 public String toString()
147 return this.getClass().getSimpleName()+"["+_name+"]";
150 /* ------------------------------------------------------------ */
151 /** Put user into realm.
152 * Called by implementations to put the user data loaded from
153 * file/db etc into the user structure.
154 * @param userName User name
155 * @param info a UserIdentity instance, or a String password or Credential instance
156 * @return User instance
158 protected synchronized UserIdentity putUser(String userName, Object info)
160 final UserIdentity identity;
161 if (info instanceof UserIdentity)
162 identity=(UserIdentity)info;
165 Credential credential = (info instanceof Credential)?(Credential)info:Credential.getCredential(info.toString());
167 Principal userPrincipal = new KnownUser(userName,credential);
168 Subject subject = new Subject();
169 subject.getPrincipals().add(userPrincipal);
170 subject.getPrivateCredentials().add(credential);
171 subject.setReadOnly();
172 identity=_identityService.newUserIdentity(subject,userPrincipal,IdentityService.NO_ROLES);
175 _users.put(userName,identity);
179 /* ------------------------------------------------------------ */
180 /** Put user into realm.
181 * @param userName The user to add
182 * @param credential The users Credentials
183 * @param roles The users roles
184 * @return UserIdentity
186 public synchronized UserIdentity putUser(String userName, Credential credential, String[] roles)
188 Principal userPrincipal = new KnownUser(userName,credential);
189 Subject subject = new Subject();
190 subject.getPrincipals().add(userPrincipal);
191 subject.getPrivateCredentials().add(credential);
194 for (String role : roles)
195 subject.getPrincipals().add(new RolePrincipal(role));
197 subject.setReadOnly();
198 UserIdentity identity=_identityService.newUserIdentity(subject,userPrincipal,roles);
199 _users.put(userName,identity);
203 /* ------------------------------------------------------------ */
204 public void removeUser(String username)
206 _users.remove(username);
209 /* ------------------------------------------------------------ */
211 * @see org.eclipse.jetty.security.LoginService#login(java.lang.String, java.lang.Object)
213 public UserIdentity login(String username, Object credentials)
215 if (username == null)
218 UserIdentity user = _users.get(username);
221 user = loadUser(username);
225 UserPrincipal principal = (UserPrincipal)user.getUserPrincipal();
226 if (principal.authenticate(credentials))
232 /* ------------------------------------------------------------ */
233 public boolean validate(UserIdentity user)
235 if (_users.containsKey(user.getUserPrincipal().getName()))
238 if (loadUser(user.getUserPrincipal().getName())!=null)
244 /* ------------------------------------------------------------ */
245 protected abstract UserIdentity loadUser(String username);
247 /* ------------------------------------------------------------ */
248 protected abstract void loadUsers() throws IOException;
251 /* ------------------------------------------------------------ */
252 /* ------------------------------------------------------------ */
253 /* ------------------------------------------------------------ */
254 public interface UserPrincipal extends Principal,Serializable
256 boolean authenticate(Object credentials);
257 public boolean isAuthenticated();
260 /* ------------------------------------------------------------ */
261 /* ------------------------------------------------------------ */
262 /* ------------------------------------------------------------ */
263 public static class RolePrincipal implements Principal,Serializable
265 private static final long serialVersionUID = 2998397924051854402L;
266 private final String _roleName;
267 public RolePrincipal(String name)
271 public String getName()
277 /* ------------------------------------------------------------ */
278 /* ------------------------------------------------------------ */
279 /* ------------------------------------------------------------ */
280 public static class Anonymous implements UserPrincipal,Serializable
282 private static final long serialVersionUID = 1097640442553284845L;
284 public boolean isAuthenticated()
289 public String getName()
294 public boolean authenticate(Object credentials)
301 /* ------------------------------------------------------------ */
302 /* ------------------------------------------------------------ */
303 /* ------------------------------------------------------------ */
304 public static class KnownUser implements UserPrincipal,Serializable
306 private static final long serialVersionUID = -6226920753748399662L;
307 private final String _name;
308 private final Credential _credential;
310 /* -------------------------------------------------------- */
311 public KnownUser(String name,Credential credential)
314 _credential=credential;
317 /* -------------------------------------------------------- */
318 public boolean authenticate(Object credentials)
320 return _credential!=null && _credential.check(credentials);
323 /* ------------------------------------------------------------ */
324 public String getName()
329 /* -------------------------------------------------------- */
330 public boolean isAuthenticated()
335 /* -------------------------------------------------------- */
337 public String toString()