Refactor jaas login sequence to only fetch role data if user is authenticated according to that module.
This commit is contained in:
parent
e296995b2f
commit
c7ab05a0b8
|
@ -21,7 +21,6 @@ package org.eclipse.jetty.jaas.spi;
|
|||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -61,6 +60,24 @@ public abstract class AbstractDatabaseLoginModule extends AbstractLoginModule
|
|||
public abstract Connection getConnection () throws Exception;
|
||||
|
||||
|
||||
public class JDBCUserInfo extends UserInfo
|
||||
{
|
||||
public JDBCUserInfo (String userName, Credential credential)
|
||||
{
|
||||
super(userName, credential);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public List<String> doFetchRoles ()
|
||||
throws Exception
|
||||
{
|
||||
return getRoles(getUserName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------ */
|
||||
/** Load info from database
|
||||
|
@ -92,8 +109,22 @@ public abstract class AbstractDatabaseLoginModule extends AbstractLoginModule
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return new JDBCUserInfo (userName, Credential.getCredential(dbCredential));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public List<String> getRoles (String userName)
|
||||
throws Exception
|
||||
{
|
||||
List<String> roles = new ArrayList<String>();
|
||||
|
||||
try (Connection connection = getConnection())
|
||||
{
|
||||
//query for role names
|
||||
List<String> roles = new ArrayList<String>();
|
||||
|
||||
try (PreparedStatement statement = connection.prepareStatement (rolesQuery))
|
||||
{
|
||||
statement.setString (1, userName);
|
||||
|
@ -107,11 +138,14 @@ public abstract class AbstractDatabaseLoginModule extends AbstractLoginModule
|
|||
}
|
||||
}
|
||||
|
||||
return new UserInfo (userName, Credential.getCredential(dbCredential), roles);
|
||||
}
|
||||
|
||||
return roles;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public void initialize(Subject subject,
|
||||
CallbackHandler callbackHandler,
|
||||
Map<String,?> sharedState,
|
||||
|
|
|
@ -54,6 +54,12 @@ public abstract class AbstractLoginModule implements LoginModule
|
|||
private JAASUserInfo currentUser;
|
||||
private Subject subject;
|
||||
|
||||
/**
|
||||
* JAASUserInfo
|
||||
*
|
||||
* This class unites the UserInfo data with jaas concepts
|
||||
* such as Subject and Principals
|
||||
*/
|
||||
public class JAASUserInfo
|
||||
{
|
||||
private UserInfo user;
|
||||
|
@ -62,7 +68,8 @@ public abstract class AbstractLoginModule implements LoginModule
|
|||
|
||||
public JAASUserInfo (UserInfo u)
|
||||
{
|
||||
setUserInfo(u);
|
||||
this.user = u;
|
||||
this.principal = new JAASPrincipal(u.getUserName());
|
||||
}
|
||||
|
||||
public String getUserName ()
|
||||
|
@ -75,18 +82,6 @@ public abstract class AbstractLoginModule implements LoginModule
|
|||
return this.principal;
|
||||
}
|
||||
|
||||
public void setUserInfo (UserInfo u)
|
||||
{
|
||||
this.user = u;
|
||||
this.principal = new JAASPrincipal(u.getUserName());
|
||||
this.roles = new ArrayList<JAASRole>();
|
||||
if (u.getRoleNames() != null)
|
||||
{
|
||||
Iterator<String> itor = u.getRoleNames().iterator();
|
||||
while (itor.hasNext())
|
||||
this.roles.add(new JAASRole((String)itor.next()));
|
||||
}
|
||||
}
|
||||
|
||||
public void setJAASInfo (Subject subject)
|
||||
{
|
||||
|
@ -106,6 +101,18 @@ public abstract class AbstractLoginModule implements LoginModule
|
|||
{
|
||||
return this.user.checkCredential(suppliedCredential);
|
||||
}
|
||||
|
||||
public void fetchRoles() throws Exception
|
||||
{
|
||||
this.user.fetchRoles();
|
||||
this.roles = new ArrayList<JAASRole>();
|
||||
if (this.user.getRoleNames() != null)
|
||||
{
|
||||
Iterator<String> itor = this.user.getRoleNames().iterator();
|
||||
while (itor.hasNext())
|
||||
this.roles.add(new JAASRole((String)itor.next()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Subject getSubject ()
|
||||
|
@ -174,7 +181,6 @@ public abstract class AbstractLoginModule implements LoginModule
|
|||
*/
|
||||
public boolean commit() throws LoginException
|
||||
{
|
||||
|
||||
if (!isAuthenticated())
|
||||
{
|
||||
currentUser = null;
|
||||
|
@ -252,7 +258,10 @@ public abstract class AbstractLoginModule implements LoginModule
|
|||
setAuthenticated(currentUser.checkCredential(webCredential));
|
||||
|
||||
if (isAuthenticated())
|
||||
{
|
||||
currentUser.fetchRoles();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
throw new FailedLoginException();
|
||||
}
|
||||
|
|
|
@ -176,6 +176,28 @@ public class LdapLoginModule extends AbstractLoginModule
|
|||
|
||||
private DirContext _rootContext;
|
||||
|
||||
|
||||
public class LDAPUserInfo extends UserInfo
|
||||
{
|
||||
|
||||
/**
|
||||
* @param userName
|
||||
* @param credential
|
||||
*/
|
||||
public LDAPUserInfo(String userName, Credential credential)
|
||||
{
|
||||
super(userName, credential);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> doFetchRoles() throws Exception
|
||||
{
|
||||
return getUserRoles(_rootContext, getUserName());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get the available information about the user
|
||||
* <p>
|
||||
|
@ -199,9 +221,7 @@ public class LdapLoginModule extends AbstractLoginModule
|
|||
|
||||
pwdCredential = convertCredentialLdapToJetty(pwdCredential);
|
||||
Credential credential = Credential.getCredential(pwdCredential);
|
||||
List<String> roles = getUserRoles(_rootContext, username);
|
||||
|
||||
return new UserInfo(username, credential, roles);
|
||||
return new LDAPUserInfo(username, credential);
|
||||
}
|
||||
|
||||
protected String doRFC2254Encoding(String inputString)
|
||||
|
@ -411,12 +431,17 @@ public class LdapLoginModule extends AbstractLoginModule
|
|||
|
||||
setCurrentUser(new JAASUserInfo(userInfo));
|
||||
|
||||
boolean authed = false;
|
||||
if (webCredential instanceof String)
|
||||
{
|
||||
return credentialLogin(Credential.getCredential((String) webCredential));
|
||||
}
|
||||
authed = credentialLogin(Credential.getCredential((String) webCredential));
|
||||
else
|
||||
authed = credentialLogin(webCredential);
|
||||
|
||||
return credentialLogin(webCredential);
|
||||
//only fetch roles if authenticated
|
||||
if (authed)
|
||||
getCurrentUser().fetchRoles();
|
||||
|
||||
return authed;
|
||||
}
|
||||
catch (UnsupportedCallbackException e)
|
||||
{
|
||||
|
@ -496,16 +521,18 @@ public class LdapLoginModule extends AbstractLoginModule
|
|||
|
||||
String filter = "(&(objectClass={0})({1}={2}))";
|
||||
|
||||
LOG.info("Searching for users with filter: \'" + filter + "\'" + " from base dn: " + _userBaseDn);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Searching for users with filter: \'" + filter + "\'" + " from base dn: " + _userBaseDn);
|
||||
|
||||
Object[] filterArguments = new Object[]{
|
||||
_userObjectClass,
|
||||
_userIdAttribute,
|
||||
username
|
||||
_userObjectClass,
|
||||
_userIdAttribute,
|
||||
username
|
||||
};
|
||||
NamingEnumeration<SearchResult> results = _rootContext.search(_userBaseDn, filter, filterArguments, ctls);
|
||||
|
||||
LOG.info("Found user?: " + results.hasMoreElements());
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Found user?: " + results.hasMoreElements());
|
||||
|
||||
if (!results.hasMoreElements())
|
||||
{
|
||||
|
|
|
@ -101,7 +101,7 @@ public class PropertyFileLoginModule extends AbstractLoginModule
|
|||
}
|
||||
|
||||
/**
|
||||
* Don't implement this as we want to pre-fetch all of the users.
|
||||
*
|
||||
*
|
||||
* @param userName the user name
|
||||
* @throws Exception if unable to get the user information
|
||||
|
@ -117,6 +117,8 @@ public class PropertyFileLoginModule extends AbstractLoginModule
|
|||
if (userIdentity==null)
|
||||
return null;
|
||||
|
||||
//TODO in future versions change the impl of PropertyUserStore so its not
|
||||
//storing Subjects etc, just UserInfo
|
||||
Set<Principal> principals = userIdentity.getSubject().getPrincipals();
|
||||
|
||||
List<String> roles = new ArrayList<String>();
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
package org.eclipse.jetty.jaas.spi;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.util.security.Credential;
|
||||
|
@ -29,24 +30,70 @@ import org.eclipse.jetty.util.security.Credential;
|
|||
* This is the information read from the external source
|
||||
* about a user.
|
||||
*
|
||||
* Can be cached by a UserInfoCache implementation
|
||||
* Can be cached.
|
||||
*/
|
||||
public class UserInfo
|
||||
{
|
||||
|
||||
private String _userName;
|
||||
private Credential _credential;
|
||||
private List<String> _roleNames;
|
||||
protected List<String> _roleNames = new ArrayList<>();
|
||||
protected boolean _rolesLoaded = false;
|
||||
|
||||
|
||||
/**
|
||||
* @param userName
|
||||
* @param credential
|
||||
* @param roleNames
|
||||
*/
|
||||
public UserInfo (String userName, Credential credential, List<String> roleNames)
|
||||
{
|
||||
_userName = userName;
|
||||
_credential = credential;
|
||||
_roleNames = new ArrayList<String>();
|
||||
if (roleNames != null)
|
||||
{
|
||||
_roleNames.addAll(roleNames);
|
||||
synchronized (_roleNames)
|
||||
{
|
||||
_roleNames.addAll(roleNames);
|
||||
_rolesLoaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param userName
|
||||
* @param credential
|
||||
*/
|
||||
public UserInfo (String userName, Credential credential)
|
||||
{
|
||||
this (userName, credential, null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Should be overridden by subclasses to obtain
|
||||
* role info
|
||||
*
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public List<String> doFetchRoles ()
|
||||
throws Exception
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public void fetchRoles () throws Exception
|
||||
{
|
||||
synchronized (_roleNames)
|
||||
{
|
||||
if (!_rolesLoaded)
|
||||
{
|
||||
_roleNames.addAll(doFetchRoles());
|
||||
_rolesLoaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,7 +104,7 @@ public class UserInfo
|
|||
|
||||
public List<String> getRoleNames ()
|
||||
{
|
||||
return new ArrayList<String>(_roleNames);
|
||||
return Collections.unmodifiableList(_roleNames);
|
||||
}
|
||||
|
||||
public boolean checkCredential (Object suppliedCredential)
|
||||
|
|
|
@ -74,6 +74,33 @@ public class DataSourceLoginService extends MappedLoginService
|
|||
private String _roleSql;
|
||||
private boolean _createTables = false;
|
||||
|
||||
|
||||
/**
|
||||
* DBUser
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class DBUser extends KnownUser
|
||||
{
|
||||
private int _key;
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @param credential
|
||||
*/
|
||||
public DBUser(String name, Credential credential, int key)
|
||||
{
|
||||
super(name, credential);
|
||||
_key = key;
|
||||
}
|
||||
|
||||
public int getKey ()
|
||||
{
|
||||
return _key;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public DataSourceLoginService()
|
||||
{
|
||||
|
@ -290,13 +317,13 @@ public class DataSourceLoginService extends MappedLoginService
|
|||
*
|
||||
* @param userName the user name
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
protected UserIdentity loadUser (String userName)
|
||||
{
|
||||
try
|
||||
{
|
||||
try (Connection connection = getConnection();
|
||||
PreparedStatement statement1 = connection.prepareStatement(_userSql))
|
||||
PreparedStatement statement1 = connection.prepareStatement(_userSql))
|
||||
{
|
||||
statement1.setObject(1, userName);
|
||||
try (ResultSet rs1 = statement1.executeQuery())
|
||||
|
@ -305,19 +332,20 @@ public class DataSourceLoginService extends MappedLoginService
|
|||
{
|
||||
int key = rs1.getInt(_userTableKey);
|
||||
String credentials = rs1.getString(_userTablePasswordField);
|
||||
List<String> roles = new ArrayList<String>();
|
||||
try (PreparedStatement statement2 = connection.prepareStatement(_roleSql))
|
||||
{
|
||||
statement2.setInt(1, key);
|
||||
try (ResultSet rs2 = statement2.executeQuery())
|
||||
|
||||
List<String> roles = new ArrayList<String>();
|
||||
try (PreparedStatement statement2 = connection.prepareStatement(_roleSql))
|
||||
{
|
||||
while (rs2.next())
|
||||
statement2.setInt(1, key);
|
||||
try (ResultSet rs2 = statement2.executeQuery())
|
||||
{
|
||||
roles.add(rs2.getString(_roleTableRoleField));
|
||||
while (rs2.next())
|
||||
{
|
||||
roles.add(rs2.getString(_roleTableRoleField));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return putUser(userName, Credential.getCredential(credentials), roles.toArray(new String[roles.size()]));
|
||||
return putUser(userName, Credential.getCredential(credentials), roles.toArray(new String[roles.size()]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -334,6 +362,83 @@ public class DataSourceLoginService extends MappedLoginService
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.security.MappedLoginService#loadUserInfo(java.lang.String)
|
||||
* @Override
|
||||
*/
|
||||
public KnownUser loadUserInfo (String username)
|
||||
{
|
||||
try
|
||||
{
|
||||
try (Connection connection = getConnection();
|
||||
PreparedStatement statement1 = connection.prepareStatement(_userSql))
|
||||
{
|
||||
statement1.setObject(1, username);
|
||||
try (ResultSet rs1 = statement1.executeQuery())
|
||||
{
|
||||
if (rs1.next())
|
||||
{
|
||||
int key = rs1.getInt(_userTableKey);
|
||||
String credentials = rs1.getString(_userTablePasswordField);
|
||||
|
||||
return new DBUser(username, Credential.getCredential(credentials), key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (NamingException e)
|
||||
{
|
||||
LOG.warn("No datasource for "+_jndiName, e);
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
LOG.warn("Problem loading user info for "+username, e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.security.MappedLoginService#loadRoleInfo(org.eclipse.jetty.security.MappedLoginService.KnownUser)
|
||||
* @Override
|
||||
*/
|
||||
public String[] loadRoleInfo (KnownUser user)
|
||||
{
|
||||
DBUser dbuser = (DBUser)user;
|
||||
|
||||
try
|
||||
{
|
||||
try (Connection connection = getConnection();
|
||||
PreparedStatement statement2 = connection.prepareStatement(_roleSql))
|
||||
{
|
||||
|
||||
List<String> roles = new ArrayList<String>();
|
||||
|
||||
statement2.setInt(1, dbuser.getKey());
|
||||
try (ResultSet rs2 = statement2.executeQuery())
|
||||
{
|
||||
while (rs2.next())
|
||||
{
|
||||
roles.add(rs2.getString(_roleTableRoleField));
|
||||
}
|
||||
|
||||
return roles.toArray(new String[roles.size()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (NamingException e)
|
||||
{
|
||||
LOG.warn("No datasource for "+_jndiName, e);
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
LOG.warn("Problem loading user info for "+user.getName(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
|
|
|
@ -19,7 +19,11 @@
|
|||
package org.eclipse.jetty.security;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jetty.security.MappedLoginService.KnownUser;
|
||||
import org.eclipse.jetty.security.PropertyUserStore.UserListener;
|
||||
import org.eclipse.jetty.server.UserIdentity;
|
||||
import org.eclipse.jetty.util.Scanner;
|
||||
|
@ -55,6 +59,36 @@ public class HashLoginService extends MappedLoginService implements UserListener
|
|||
private Scanner _scanner;
|
||||
private boolean hotReload = false; // default is not to reload
|
||||
|
||||
|
||||
|
||||
public class HashKnownUser extends KnownUser
|
||||
{
|
||||
String[] _roles;
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @param credential
|
||||
*/
|
||||
public HashKnownUser(String name, Credential credential)
|
||||
{
|
||||
super(name, credential);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setRoles (String[] roles)
|
||||
{
|
||||
_roles = roles;
|
||||
}
|
||||
|
||||
public String[] getRoles()
|
||||
{
|
||||
return _roles;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public HashLoginService()
|
||||
{
|
||||
|
@ -163,6 +197,41 @@ public class HashLoginService extends MappedLoginService implements UserListener
|
|||
// TODO: Consider refactoring MappedLoginService to not have to override with unused methods
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected String[] loadRoleInfo(KnownUser user)
|
||||
{
|
||||
UserIdentity id = _propertyUserStore.getUserIdentity(user.getName());
|
||||
if (id == null)
|
||||
return null;
|
||||
|
||||
|
||||
Set<RolePrincipal> roles = id.getSubject().getPrincipals(RolePrincipal.class);
|
||||
if (roles == null)
|
||||
return null;
|
||||
|
||||
List<String> list = new ArrayList<>();
|
||||
for (RolePrincipal r:roles)
|
||||
list.add(r.getName());
|
||||
|
||||
return list.toArray(new String[roles.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected KnownUser loadUserInfo(String userName)
|
||||
{
|
||||
UserIdentity id = _propertyUserStore.getUserIdentity(userName);
|
||||
if (id != null)
|
||||
{
|
||||
return (KnownUser)id.getUserPrincipal();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
|
||||
|
@ -204,9 +273,11 @@ public class HashLoginService extends MappedLoginService implements UserListener
|
|||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("update: " + userName + " Roles: " + roleArray.length);
|
||||
putUser(userName,credential,roleArray);
|
||||
//TODO need to remove and replace the authenticated user?
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
public void remove(String userName)
|
||||
|
|
|
@ -78,6 +78,32 @@ public class JDBCLoginService extends MappedLoginService
|
|||
protected String _roleSql;
|
||||
|
||||
|
||||
/**
|
||||
* JDBCKnownUser
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class JDBCKnownUser extends KnownUser
|
||||
{
|
||||
int _userKey;
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* @param credential
|
||||
*/
|
||||
public JDBCKnownUser(String name, Credential credential, int key)
|
||||
{
|
||||
super(name, credential);
|
||||
_userKey = key;
|
||||
}
|
||||
|
||||
|
||||
public int getUserKey ()
|
||||
{
|
||||
return _userKey;
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public JDBCLoginService()
|
||||
throws IOException
|
||||
|
@ -231,7 +257,7 @@ public class JDBCLoginService extends MappedLoginService
|
|||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
@Deprecated
|
||||
protected UserIdentity loadUser(String username)
|
||||
{
|
||||
try
|
||||
|
@ -251,6 +277,8 @@ public class JDBCLoginService extends MappedLoginService
|
|||
{
|
||||
int key = rs1.getInt(_userTableKey);
|
||||
String credentials = rs1.getString(_userTablePasswordField);
|
||||
|
||||
|
||||
List<String> roles = new ArrayList<String>();
|
||||
|
||||
try (PreparedStatement stat2 = _con.prepareStatement(_roleSql))
|
||||
|
@ -262,7 +290,7 @@ public class JDBCLoginService extends MappedLoginService
|
|||
roles.add(rs2.getString(_roleTableRoleField));
|
||||
}
|
||||
}
|
||||
return putUser(username, credentials, roles.toArray(new String[roles.size()]));
|
||||
return putUser(username, Credential.getCredential(credentials), roles.toArray(new String[roles.size()]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -275,13 +303,89 @@ public class JDBCLoginService extends MappedLoginService
|
|||
return null;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
protected UserIdentity putUser (String username, String credentials, String[] roles)
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.security.MappedLoginService#loadUserInfo(java.lang.String)
|
||||
* @Override
|
||||
*/
|
||||
public KnownUser loadUserInfo (String username)
|
||||
{
|
||||
return putUser(username, Credential.getCredential(credentials),roles);
|
||||
try
|
||||
{
|
||||
if (null == _con)
|
||||
connectDatabase();
|
||||
|
||||
if (null == _con)
|
||||
throw new SQLException("Can't connect to database");
|
||||
|
||||
try (PreparedStatement stat1 = _con.prepareStatement(_userSql))
|
||||
{
|
||||
stat1.setObject(1, username);
|
||||
try (ResultSet rs1 = stat1.executeQuery())
|
||||
{
|
||||
if (rs1.next())
|
||||
{
|
||||
int key = rs1.getInt(_userTableKey);
|
||||
String credentials = rs1.getString(_userTablePasswordField);
|
||||
|
||||
return new JDBCKnownUser (username, Credential.getCredential(credentials), key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
LOG.warn("UserRealm " + getName() + " could not load user information from database", e);
|
||||
closeConnection();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.security.MappedLoginService#loadRoleInfo(org.eclipse.jetty.security.MappedLoginService.KnownUser)
|
||||
* @Override
|
||||
*/
|
||||
public String[] loadRoleInfo (KnownUser user)
|
||||
{
|
||||
JDBCKnownUser jdbcUser = (JDBCKnownUser)user;
|
||||
|
||||
try
|
||||
{
|
||||
if (null == _con)
|
||||
connectDatabase();
|
||||
|
||||
if (null == _con)
|
||||
throw new SQLException("Can't connect to database");
|
||||
|
||||
|
||||
List<String> roles = new ArrayList<String>();
|
||||
|
||||
try (PreparedStatement stat2 = _con.prepareStatement(_roleSql))
|
||||
{
|
||||
stat2.setInt(1, jdbcUser.getUserKey());
|
||||
try (ResultSet rs2 = stat2.executeQuery())
|
||||
{
|
||||
while (rs2.next())
|
||||
roles.add(rs2.getString(_roleTableRoleField));
|
||||
return roles.toArray(new String[roles.size()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
LOG.warn("UserRealm " + getName() + " could not load user information from database", e);
|
||||
closeConnection();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Close an existing connection
|
||||
*/
|
||||
|
|
|
@ -139,6 +139,8 @@ public abstract class MappedLoginService extends AbstractLifeCycle implements Lo
|
|||
public void logout(UserIdentity identity)
|
||||
{
|
||||
LOG.debug("logout {}",identity);
|
||||
|
||||
//TODO should remove the user?????
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -201,6 +203,24 @@ public abstract class MappedLoginService extends AbstractLifeCycle implements Lo
|
|||
return identity;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public synchronized UserIdentity putUser (KnownUser userPrincipal, String[] roles)
|
||||
{
|
||||
Subject subject = new Subject();
|
||||
subject.getPrincipals().add(userPrincipal);
|
||||
subject.getPrivateCredentials().add(userPrincipal._credential);
|
||||
if (roles!=null)
|
||||
for (String role : roles)
|
||||
subject.getPrincipals().add(new RolePrincipal(role));
|
||||
subject.setReadOnly();
|
||||
UserIdentity identity=_identityService.newUserIdentity(subject,userPrincipal,roles);
|
||||
_users.put(userPrincipal._name,identity);
|
||||
return identity;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void removeUser(String username)
|
||||
{
|
||||
|
@ -219,9 +239,17 @@ public abstract class MappedLoginService extends AbstractLifeCycle implements Lo
|
|||
UserIdentity user = _users.get(username);
|
||||
|
||||
if (user==null)
|
||||
user = loadUser(username);
|
||||
|
||||
if (user!=null)
|
||||
{
|
||||
KnownUser userPrincipal = loadUserInfo(username);
|
||||
if (userPrincipal.authenticate(credentials))
|
||||
{
|
||||
//safe to load the roles
|
||||
String[] roles = loadRoleInfo(userPrincipal);
|
||||
user = putUser(userPrincipal, roles);
|
||||
return user;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UserPrincipal principal = (UserPrincipal)user.getUserPrincipal();
|
||||
if (principal.authenticate(credentials))
|
||||
|
@ -241,7 +269,10 @@ public abstract class MappedLoginService extends AbstractLifeCycle implements Lo
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
protected abstract String[] loadRoleInfo (KnownUser user);
|
||||
/* ------------------------------------------------------------ */
|
||||
protected abstract KnownUser loadUserInfo (String username);
|
||||
/* ------------------------------------------------------------ */
|
||||
protected abstract UserIdentity loadUser(String username);
|
||||
|
||||
|
|
|
@ -50,6 +50,13 @@
|
|||
</securityHandler>
|
||||
</webAppConfig>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>5.1.19</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
xyz {
|
||||
org.eclipse.jetty.jaas.spi.PropertyFileLoginModule required
|
||||
org.eclipse.jetty.jaas.spi.JDBCLoginModule required
|
||||
debug="true"
|
||||
file="${jetty.base}/etc/login.properties";
|
||||
userTable="users"
|
||||
userField="username"
|
||||
credentialField="pwd"
|
||||
userRoleTable="userroles"
|
||||
userRoleUserField="username"
|
||||
userRoleRoleField="rolename"
|
||||
dbDriver="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource"
|
||||
dbUrl="jdbc:mysql://localhost:3306/jaas"
|
||||
dbUserName="janb";
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue