Refactor jaas login sequence to only fetch role data if user is authenticated according to that module.

This commit is contained in:
Jan Bartel 2015-11-25 13:58:27 +11:00
parent e296995b2f
commit c7ab05a0b8
11 changed files with 508 additions and 63 deletions

View File

@ -21,7 +21,6 @@ package org.eclipse.jetty.jaas.spi;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -61,6 +60,24 @@ public abstract class AbstractDatabaseLoginModule extends AbstractLoginModule
public abstract Connection getConnection () throws Exception; 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 /** Load info from database
@ -92,8 +109,22 @@ public abstract class AbstractDatabaseLoginModule extends AbstractLoginModule
return null; 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 //query for role names
List<String> roles = new ArrayList<String>();
try (PreparedStatement statement = connection.prepareStatement (rolesQuery)) try (PreparedStatement statement = connection.prepareStatement (rolesQuery))
{ {
statement.setString (1, userName); 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, public void initialize(Subject subject,
CallbackHandler callbackHandler, CallbackHandler callbackHandler,
Map<String,?> sharedState, Map<String,?> sharedState,

View File

@ -54,6 +54,12 @@ public abstract class AbstractLoginModule implements LoginModule
private JAASUserInfo currentUser; private JAASUserInfo currentUser;
private Subject subject; private Subject subject;
/**
* JAASUserInfo
*
* This class unites the UserInfo data with jaas concepts
* such as Subject and Principals
*/
public class JAASUserInfo public class JAASUserInfo
{ {
private UserInfo user; private UserInfo user;
@ -62,7 +68,8 @@ public abstract class AbstractLoginModule implements LoginModule
public JAASUserInfo (UserInfo u) public JAASUserInfo (UserInfo u)
{ {
setUserInfo(u); this.user = u;
this.principal = new JAASPrincipal(u.getUserName());
} }
public String getUserName () public String getUserName ()
@ -75,18 +82,6 @@ public abstract class AbstractLoginModule implements LoginModule
return this.principal; 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) public void setJAASInfo (Subject subject)
{ {
@ -106,6 +101,18 @@ public abstract class AbstractLoginModule implements LoginModule
{ {
return this.user.checkCredential(suppliedCredential); 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 () public Subject getSubject ()
@ -174,7 +181,6 @@ public abstract class AbstractLoginModule implements LoginModule
*/ */
public boolean commit() throws LoginException public boolean commit() throws LoginException
{ {
if (!isAuthenticated()) if (!isAuthenticated())
{ {
currentUser = null; currentUser = null;
@ -252,7 +258,10 @@ public abstract class AbstractLoginModule implements LoginModule
setAuthenticated(currentUser.checkCredential(webCredential)); setAuthenticated(currentUser.checkCredential(webCredential));
if (isAuthenticated()) if (isAuthenticated())
{
currentUser.fetchRoles();
return true; return true;
}
else else
throw new FailedLoginException(); throw new FailedLoginException();
} }

View File

@ -176,6 +176,28 @@ public class LdapLoginModule extends AbstractLoginModule
private DirContext _rootContext; 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 * get the available information about the user
* <p> * <p>
@ -199,9 +221,7 @@ public class LdapLoginModule extends AbstractLoginModule
pwdCredential = convertCredentialLdapToJetty(pwdCredential); pwdCredential = convertCredentialLdapToJetty(pwdCredential);
Credential credential = Credential.getCredential(pwdCredential); Credential credential = Credential.getCredential(pwdCredential);
List<String> roles = getUserRoles(_rootContext, username); return new LDAPUserInfo(username, credential);
return new UserInfo(username, credential, roles);
} }
protected String doRFC2254Encoding(String inputString) protected String doRFC2254Encoding(String inputString)
@ -411,12 +431,17 @@ public class LdapLoginModule extends AbstractLoginModule
setCurrentUser(new JAASUserInfo(userInfo)); setCurrentUser(new JAASUserInfo(userInfo));
boolean authed = false;
if (webCredential instanceof String) if (webCredential instanceof String)
{ authed = credentialLogin(Credential.getCredential((String) webCredential));
return 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) catch (UnsupportedCallbackException e)
{ {
@ -496,16 +521,18 @@ public class LdapLoginModule extends AbstractLoginModule
String filter = "(&(objectClass={0})({1}={2}))"; 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[]{ Object[] filterArguments = new Object[]{
_userObjectClass, _userObjectClass,
_userIdAttribute, _userIdAttribute,
username username
}; };
NamingEnumeration<SearchResult> results = _rootContext.search(_userBaseDn, filter, filterArguments, ctls); 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()) if (!results.hasMoreElements())
{ {

View File

@ -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 * @param userName the user name
* @throws Exception if unable to get the user information * @throws Exception if unable to get the user information
@ -117,6 +117,8 @@ public class PropertyFileLoginModule extends AbstractLoginModule
if (userIdentity==null) if (userIdentity==null)
return 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(); Set<Principal> principals = userIdentity.getSubject().getPrincipals();
List<String> roles = new ArrayList<String>(); List<String> roles = new ArrayList<String>();

View File

@ -19,6 +19,7 @@
package org.eclipse.jetty.jaas.spi; package org.eclipse.jetty.jaas.spi;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import org.eclipse.jetty.util.security.Credential; 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 * This is the information read from the external source
* about a user. * about a user.
* *
* Can be cached by a UserInfoCache implementation * Can be cached.
*/ */
public class UserInfo public class UserInfo
{ {
private String _userName; private String _userName;
private Credential _credential; 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) public UserInfo (String userName, Credential credential, List<String> roleNames)
{ {
_userName = userName; _userName = userName;
_credential = credential; _credential = credential;
_roleNames = new ArrayList<String>();
if (roleNames != null) 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 () public List<String> getRoleNames ()
{ {
return new ArrayList<String>(_roleNames); return Collections.unmodifiableList(_roleNames);
} }
public boolean checkCredential (Object suppliedCredential) public boolean checkCredential (Object suppliedCredential)

View File

@ -74,6 +74,33 @@ public class DataSourceLoginService extends MappedLoginService
private String _roleSql; private String _roleSql;
private boolean _createTables = false; 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() public DataSourceLoginService()
{ {
@ -290,13 +317,13 @@ public class DataSourceLoginService extends MappedLoginService
* *
* @param userName the user name * @param userName the user name
*/ */
@Override @Deprecated
protected UserIdentity loadUser (String userName) protected UserIdentity loadUser (String userName)
{ {
try try
{ {
try (Connection connection = getConnection(); try (Connection connection = getConnection();
PreparedStatement statement1 = connection.prepareStatement(_userSql)) PreparedStatement statement1 = connection.prepareStatement(_userSql))
{ {
statement1.setObject(1, userName); statement1.setObject(1, userName);
try (ResultSet rs1 = statement1.executeQuery()) try (ResultSet rs1 = statement1.executeQuery())
@ -305,19 +332,20 @@ public class DataSourceLoginService extends MappedLoginService
{ {
int key = rs1.getInt(_userTableKey); int key = rs1.getInt(_userTableKey);
String credentials = rs1.getString(_userTablePasswordField); String credentials = rs1.getString(_userTablePasswordField);
List<String> roles = new ArrayList<String>();
try (PreparedStatement statement2 = connection.prepareStatement(_roleSql)) List<String> roles = new ArrayList<String>();
{ try (PreparedStatement statement2 = connection.prepareStatement(_roleSql))
statement2.setInt(1, key);
try (ResultSet rs2 = statement2.executeQuery())
{ {
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 @Override

View File

@ -19,7 +19,11 @@
package org.eclipse.jetty.security; package org.eclipse.jetty.security;
import java.io.IOException; 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.security.PropertyUserStore.UserListener;
import org.eclipse.jetty.server.UserIdentity; import org.eclipse.jetty.server.UserIdentity;
import org.eclipse.jetty.util.Scanner; import org.eclipse.jetty.util.Scanner;
@ -55,6 +59,36 @@ public class HashLoginService extends MappedLoginService implements UserListener
private Scanner _scanner; private Scanner _scanner;
private boolean hotReload = false; // default is not to reload 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() 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 // 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() * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
@ -204,9 +273,11 @@ public class HashLoginService extends MappedLoginService implements UserListener
{ {
if (LOG.isDebugEnabled()) if (LOG.isDebugEnabled())
LOG.debug("update: " + userName + " Roles: " + roleArray.length); LOG.debug("update: " + userName + " Roles: " + roleArray.length);
putUser(userName,credential,roleArray); //TODO need to remove and replace the authenticated user?
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@Override @Override
public void remove(String userName) public void remove(String userName)

View File

@ -78,6 +78,32 @@ public class JDBCLoginService extends MappedLoginService
protected String _roleSql; 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() public JDBCLoginService()
throws IOException throws IOException
@ -231,7 +257,7 @@ public class JDBCLoginService extends MappedLoginService
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@Override @Deprecated
protected UserIdentity loadUser(String username) protected UserIdentity loadUser(String username)
{ {
try try
@ -251,6 +277,8 @@ public class JDBCLoginService extends MappedLoginService
{ {
int key = rs1.getInt(_userTableKey); int key = rs1.getInt(_userTableKey);
String credentials = rs1.getString(_userTablePasswordField); String credentials = rs1.getString(_userTablePasswordField);
List<String> roles = new ArrayList<String>(); List<String> roles = new ArrayList<String>();
try (PreparedStatement stat2 = _con.prepareStatement(_roleSql)) try (PreparedStatement stat2 = _con.prepareStatement(_roleSql))
@ -262,7 +290,7 @@ public class JDBCLoginService extends MappedLoginService
roles.add(rs2.getString(_roleTableRoleField)); 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; 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 * Close an existing connection
*/ */

View File

@ -139,6 +139,8 @@ public abstract class MappedLoginService extends AbstractLifeCycle implements Lo
public void logout(UserIdentity identity) public void logout(UserIdentity identity)
{ {
LOG.debug("logout {}",identity); LOG.debug("logout {}",identity);
//TODO should remove the user?????
} }
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
@ -201,6 +203,24 @@ public abstract class MappedLoginService extends AbstractLifeCycle implements Lo
return identity; 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) public void removeUser(String username)
{ {
@ -219,9 +239,17 @@ public abstract class MappedLoginService extends AbstractLifeCycle implements Lo
UserIdentity user = _users.get(username); UserIdentity user = _users.get(username);
if (user==null) if (user==null)
user = loadUser(username); {
KnownUser userPrincipal = loadUserInfo(username);
if (user!=null) 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(); UserPrincipal principal = (UserPrincipal)user.getUserPrincipal();
if (principal.authenticate(credentials)) if (principal.authenticate(credentials))
@ -241,7 +269,10 @@ public abstract class MappedLoginService extends AbstractLifeCycle implements Lo
return false; return false;
} }
/* ------------------------------------------------------------ */
protected abstract String[] loadRoleInfo (KnownUser user);
/* ------------------------------------------------------------ */
protected abstract KnownUser loadUserInfo (String username);
/* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */
protected abstract UserIdentity loadUser(String username); protected abstract UserIdentity loadUser(String username);

View File

@ -50,6 +50,13 @@
</securityHandler> </securityHandler>
</webAppConfig> </webAppConfig>
</configuration> </configuration>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.19</version>
</dependency>
</dependencies>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>

View File

@ -1,5 +1,13 @@
xyz { xyz {
org.eclipse.jetty.jaas.spi.PropertyFileLoginModule required org.eclipse.jetty.jaas.spi.JDBCLoginModule required
debug="true" 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";
}; };