The problem is that once you have customized the SQL for authentication, you do not have access to an appropriate corresponding MappingSqlQuery object to be used to create the UserDetails object you need.
Specifically, the UsersByUsernameMapping is a private class extending MappingSqlQuery within the JdbcDaoImpl class and is shown here:
Code:
/**
* 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,
new GrantedAuthority[] {new GrantedAuthorityImpl("HOLDER")});
return user;
}
}
Note that the fields being extracted from the ResultSet in the mapRow() method above are not going to match the fields in the customized SQL to reflect a different db schema.
How can I set the MappingSqlQuery object that correctly maps the ResultSet returned from the customized authentication SQL? Overriding the following method from JdbcDaoImpl might work:
Code:
/**
* Executes the <tt>usersByUsernameQuery</tt> and returns a list of UserDetails objects (there should normally
* only be one matching user).
*/
protected List loadUsersByUsername(String username) {
return usersByUsernameMapping.execute(username);
}
...but this is not really what I would consider a clean solution -- I'd rather have the option of injecting my own MappingSqlQuery object and let the framework execute the appropriate method as required by the authentication process.
What do you suggest?