Finish refactoring JdbcDaoIml to remove MappingSqlQuery objects. Updated Javadoc to avoid user confusion.

This commit is contained in:
Luke Taylor 2008-12-16 18:55:38 +00:00
parent b24cc17dea
commit 74fd5fe8a4
2 changed files with 68 additions and 125 deletions

View File

@ -15,37 +15,28 @@
package org.springframework.security.userdetails.jdbc;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.springframework.context.ApplicationContextException;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;
import org.springframework.security.SpringSecurityMessageSource;
import org.springframework.security.userdetails.User;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.UserDetailsService;
import org.springframework.security.userdetails.UsernameNotFoundException;
import org.springframework.security.util.AuthorityUtils;
import org.springframework.context.ApplicationContextException;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.jdbc.object.MappingSqlQuery;
import org.springframework.util.Assert;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.List;
import java.util.ArrayList;
import java.util.Set;
import java.util.HashSet;
import javax.sql.DataSource;
/**
* <tt>UserDetailsServiceRetrieves</tt> implementation which retrieves the user details
@ -105,26 +96,23 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements UserDetailsService {
//~ Static fields/initializers =====================================================================================
public static final String DEF_USERS_BY_USERNAME_QUERY =
"SELECT username,password,enabled " +
"FROM users " +
"WHERE username = ?";
"select username,password,enabled " +
"from users " +
"where username = ?";
public static final String DEF_AUTHORITIES_BY_USERNAME_QUERY =
"SELECT username,authority " +
"FROM authorities " +
"WHERE username = ?";
"select username,authority " +
"from authorities " +
"where username = ?";
public static final String DEF_GROUP_AUTHORITIES_BY_USERNAME_QUERY =
"SELECT g.id, g.group_name, ga.authority " +
"FROM groups g, group_members gm, group_authorities ga " +
"WHERE gm.username = ? " +
"AND g.id = ga.group_id " +
"AND g.id = gm.group_id";
"select g.id, g.group_name, ga.authority " +
"from groups g, group_members gm, group_authorities ga " +
"where gm.username = ? " +
"and g.id = ga.group_id " +
"and g.id = gm.group_id";
//~ Instance fields ================================================================================================
protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
private MappingSqlQuery authoritiesByUsernameMapping;
private MappingSqlQuery groupAuthoritiesByUsernameMapping;
private MappingSqlQuery usersByUsernameMapping;
private String authoritiesByUsernameQuery;
private String groupAuthoritiesByUsernameQuery;
@ -145,8 +133,7 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements UserDetailsService {
//~ Methods ========================================================================================================
/**
* Allows subclasses to add their own granted authorities to the list to be returned in the
* <code>User</code>.
* Allows subclasses to add their own granted authorities to the list to be returned in the <tt>UserDetails</tt>.
*
* @param username the username, for use by finder methods
* @param authorities the current granted authorities, as populated from the <code>authoritiesByUsername</code>
@ -160,16 +147,6 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements UserDetailsService {
protected void initDao() throws ApplicationContextException {
Assert.isTrue(enableAuthorities || enableGroups, "Use of either authorities or groups must be enabled");
initMappingSqlQueries();
}
/**
* Extension point to allow other MappingSqlQuery objects to be substituted in a subclass
*/
private void initMappingSqlQueries() {
this.usersByUsernameMapping = new UsersByUsernameMapping(getDataSource());
this.authoritiesByUsernameMapping = new AuthoritiesByUsernameMapping(getDataSource());
this.groupAuthoritiesByUsernameMapping = new GroupAuthoritiesByUsernameMapping(getDataSource());
}
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
@ -180,7 +157,7 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements UserDetailsService {
messages.getMessage("JdbcDaoImpl.notFound", new Object[]{username}, "Username {0} not found"), username);
}
UserDetails user = (UserDetails) users.get(0); // contains no GrantedAuthority[]
UserDetails user = users.get(0); // contains no GrantedAuthority[]
Set<GrantedAuthority> dbAuthsSet = new HashSet<GrantedAuthority>();
@ -206,24 +183,51 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements UserDetailsService {
}
/**
* Executes the <tt>usersByUsernameQuery</tt> and returns a list of UserDetails objects (there should normally
* only be one matching user).
* Executes the SQL <tt>usersByUsernameQuery</tt> and returns a list of UserDetails objects.
* There should normally only be one matching user.
*/
protected List<UserDetails> loadUsersByUsername(String username) {
return usersByUsernameMapping.execute(username);
return getJdbcTemplate().query(usersByUsernameQuery, new String[] {username}, new RowMapper() {
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
String username = rs.getString(1);
String password = rs.getString(2);
boolean enabled = rs.getBoolean(3);
return new User(username, password, enabled, true, true, true, AuthorityUtils.NO_AUTHORITIES);
}
});
}
/**
* Loads authorities by executing the authoritiesByUsernameQuery.
* Loads authorities by executing the SQL from <tt>authoritiesByUsernameQuery</tt>.
*
* @return a list of GrantedAuthority objects for the user
*/
protected List<GrantedAuthority> loadUserAuthorities(String username) {
return authoritiesByUsernameMapping.execute(username);
return getJdbcTemplate().query(authoritiesByUsernameQuery, new String[] {username}, new RowMapper() {
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
String roleName = rolePrefix + rs.getString(2);
GrantedAuthorityImpl authority = new GrantedAuthorityImpl(roleName);
return authority;
}
});
}
/**
* Loads authorities by executing the SQL from <tt>groupAuthoritiesByUsernameQuery</tt>.
*
* @return a list of GrantedAuthority objects for the user
*/
protected List<GrantedAuthority> loadGroupAuthorities(String username) {
return groupAuthoritiesByUsernameMapping.execute(username);
return getJdbcTemplate().query(groupAuthoritiesByUsernameQuery, new String[] {username}, new RowMapper() {
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
String roleName = getRolePrefix() + rs.getString(3);
GrantedAuthorityImpl authority = new GrantedAuthorityImpl(roleName);
return authority;
}
});
}
/**
@ -247,12 +251,12 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements UserDetailsService {
}
/**
* Allows the default query string used to retrieve authorities based on username to be overriden, if
* Allows the default query string used to retrieve authorities based on username to be overridden, if
* default table or column names need to be changed. The default query is {@link
* #DEF_AUTHORITIES_BY_USERNAME_QUERY}; when modifying this query, ensure that all returned columns are mapped
* back to the same column names as in the default query.
*
* @param queryString The query string to set
* @param queryString The SQL query string to set
*/
public void setAuthoritiesByUsernameQuery(String queryString) {
authoritiesByUsernameQuery = queryString;
@ -263,12 +267,12 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements UserDetailsService {
}
/**
* Allows the default query string used to retrieve group authorities based on username to be overriden, if
* Allows the default query string used to retrieve group authorities based on username to be overridden, if
* default table or column names need to be changed. The default query is {@link
* #DEF_GROUP_AUTHORITIES_BY_USERNAME_QUERY}; when modifying this query, ensure that all returned columns are mapped
* back to the same column names as in the default query.
*
* @param queryString The query string to set
* @param queryString The SQL query string to set
*/
public void setGroupAuthoritiesByUsernameQuery(String queryString) {
groupAuthoritiesByUsernameQuery = queryString;
@ -309,12 +313,14 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements UserDetailsService {
}
/**
* Allows the default query string used to retrieve users based on username to be overriden, if default
* Allows the default query string used to retrieve users based on username to be overridden, if default
* table or column names need to be changed. The default query is {@link #DEF_USERS_BY_USERNAME_QUERY}; when
* modifying this query, ensure that all returned columns are mapped back to the same column names as in the
* default query. If the 'enabled' column does not exist in the source db, a permanent true value for this column
* may be returned by using a query similar to <br><pre>
* "SELECT username,password,'true' as enabled FROM users WHERE username = ?"</pre>
* default query. If the 'enabled' column does not exist in the source database, a permanent true value for this
* column may be returned by using a query similar to
* <pre>
* "select username,password,'true' as enabled from users where username = ?"
* </pre>
*
* @param usersByUsernameQueryString The query string to set
*/
@ -344,59 +350,4 @@ public class JdbcDaoImpl extends JdbcDaoSupport implements UserDetailsService {
public void setEnableGroups(boolean enableGroups) {
this.enableGroups = enableGroups;
}
//~ Inner Classes ==================================================================================================
/**
* Query object to look up a user's authorities.
*/
private class AuthoritiesByUsernameMapping extends MappingSqlQuery {
protected AuthoritiesByUsernameMapping(DataSource ds) {
super(ds, authoritiesByUsernameQuery);
declareParameter(new SqlParameter(Types.VARCHAR));
compile();
}
protected Object mapRow(ResultSet rs, int rownum) throws SQLException {
String roleName = rolePrefix + rs.getString(2);
GrantedAuthorityImpl authority = new GrantedAuthorityImpl(roleName);
return authority;
}
}
private class GroupAuthoritiesByUsernameMapping extends MappingSqlQuery {
protected GroupAuthoritiesByUsernameMapping(DataSource ds) {
super(ds, groupAuthoritiesByUsernameQuery);
declareParameter(new SqlParameter(Types.VARCHAR));
compile();
}
protected Object mapRow(ResultSet rs, int rownum) throws SQLException {
String roleName = rolePrefix + rs.getString(3);
GrantedAuthorityImpl authority = new GrantedAuthorityImpl(roleName);
return authority;
}
}
/**
* Query object to look up a user.
*/
private class UsersByUsernameMapping extends MappingSqlQuery {
protected UsersByUsernameMapping(DataSource ds) {
super(ds, usersByUsernameQuery);
declareParameter(new SqlParameter(Types.VARCHAR));
compile();
}
protected Object mapRow(ResultSet rs, int rownum) throws SQLException {
String username = rs.getString(1);
String password = rs.getString(2);
boolean enabled = rs.getBoolean(3);
UserDetails user = new User(username, password, enabled, true, true, true, AuthorityUtils.NO_AUTHORITIES);
return user;
}
}
}

View File

@ -37,14 +37,6 @@ import java.util.HashSet;
* @version $Id$
*/
public class JdbcDaoImplTests extends TestCase {
//~ Constructors ===================================================================================================
public JdbcDaoImplTests() {
}
public JdbcDaoImplTests(String arg0) {
super(arg0);
}
//~ Methods ========================================================================================================