All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.acegisecurity.userdetails.jdbc.JdbcDaoImpl Maven / Gradle / Ivy

There is a newer version: 1.0.7
Show newest version
/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.acegisecurity.userdetails.jdbc;

import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.GrantedAuthorityImpl;

import org.acegisecurity.userdetails.User;
import org.acegisecurity.userdetails.UserDetails;
import org.acegisecurity.userdetails.UserDetailsService;
import org.acegisecurity.userdetails.UsernameNotFoundException;

import org.springframework.context.ApplicationContextException;

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 java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

import java.util.List;

import javax.sql.DataSource;


/**
 * 

Retrieves user details (username, password, enabled flag, and authorities) from a JDBC location.

*

A default database structure is assumed, (see {@link #DEF_USERS_BY_USERNAME_QUERY} and {@link * #DEF_AUTHORITIES_BY_USERNAME_QUERY}, which most users of this class will need to override, if using an existing * scheme. This may be done by setting the default query strings used. If this does not provide enough flexibility, * another strategy would be to subclass this class and override the {@link MappingSqlQuery} instances used, via the * {@link #initMappingSqlQueries()} extension point.

*

In order to minimise backward compatibility issues, this DAO does not recognise the expiration of user * accounts or the expiration of user credentials. However, it does recognise and honour the user enabled/disabled * column.

* * @author Ben Alex * @author colin sampaleanu * @version $Id: JdbcDaoImpl.java 1519 2006-05-29 15:06:32Z benalex $ */ 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 = ?"; public static final String DEF_AUTHORITIES_BY_USERNAME_QUERY = "SELECT username,authority FROM authorities WHERE username = ?"; //~ Instance fields ================================================================================================ protected MappingSqlQuery authoritiesByUsernameMapping; protected MappingSqlQuery usersByUsernameMapping; private String authoritiesByUsernameQuery; private String rolePrefix = ""; private String usersByUsernameQuery; private boolean usernameBasedPrimaryKey = true; //~ Constructors =================================================================================================== public JdbcDaoImpl() { usersByUsernameQuery = DEF_USERS_BY_USERNAME_QUERY; authoritiesByUsernameQuery = DEF_AUTHORITIES_BY_USERNAME_QUERY; } //~ Methods ======================================================================================================== /** * Allows subclasses to add their own granted authorities to the list to be returned in the * User. * * @param username the username, for use by finder methods * @param authorities the current granted authorities, as populated from the authoritiesByUsername * mapping */ protected void addCustomAuthorities(String username, List authorities) {} public String getAuthoritiesByUsernameQuery() { return authoritiesByUsernameQuery; } public String getRolePrefix() { return rolePrefix; } public String getUsersByUsernameQuery() { return usersByUsernameQuery; } protected void initDao() throws ApplicationContextException { initMappingSqlQueries(); } /** * Extension point to allow other MappingSqlQuery objects to be substituted in a subclass */ protected void initMappingSqlQueries() { this.usersByUsernameMapping = new UsersByUsernameMapping(getDataSource()); this.authoritiesByUsernameMapping = new AuthoritiesByUsernameMapping(getDataSource()); } public boolean isUsernameBasedPrimaryKey() { return usernameBasedPrimaryKey; } public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException { List users = usersByUsernameMapping.execute(username); if (users.size() == 0) { throw new UsernameNotFoundException("User not found"); } UserDetails user = (UserDetails) users.get(0); // contains no GrantedAuthority[] List dbAuths = authoritiesByUsernameMapping.execute(user.getUsername()); addCustomAuthorities(user.getUsername(), dbAuths); if (dbAuths.size() == 0) { throw new UsernameNotFoundException("User has no GrantedAuthority"); } GrantedAuthority[] arrayAuths = (GrantedAuthority[]) dbAuths.toArray(new GrantedAuthority[dbAuths.size()]); String returnUsername = user.getUsername(); if (!usernameBasedPrimaryKey) { returnUsername = username; } return new User(returnUsername, user.getPassword(), user.isEnabled(), true, true, true, arrayAuths); } /** * Allows the default query string used to retrieve authorities based on username to be overriden, 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 */ public void setAuthoritiesByUsernameQuery(String queryString) { authoritiesByUsernameQuery = queryString; } /** * Allows a default role prefix to be specified. If this is set to a non-empty value, then it is * automatically prepended to any roles read in from the db. This may for example be used to add the * ROLE_ prefix expected to exist in role names (by default) by some other Acegi Security framework * classes, in the case that the prefix is not already present in the db. * * @param rolePrefix the new prefix */ public void setRolePrefix(String rolePrefix) { this.rolePrefix = rolePrefix; } /** * If true (the default), indicates the {@link #getUsersByUsernameQuery()} returns a username * in response to a query. If false, indicates that a primary key is used instead. If set to * true, the class will use the database-derived username in the returned UserDetails. * If false, the class will use the {@link #loadUserByUsername(String)} derived username in the * returned UserDetails. * * @param usernameBasedPrimaryKey true if the mapping queries return the username String, * or false if the mapping returns a database primary key. */ public void setUsernameBasedPrimaryKey(boolean usernameBasedPrimaryKey) { this.usernameBasedPrimaryKey = usernameBasedPrimaryKey; } /** * Allows the default query string used to retrieve users based on username to be overriden, 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
     * "SELECT username,password,'true' as enabled FROM users WHERE username = ?"
* * @param usersByUsernameQueryString The query string to set */ public void setUsersByUsernameQuery(String usersByUsernameQueryString) { this.usersByUsernameQuery = usersByUsernameQueryString; } //~ Inner Classes ================================================================================================== /** * Query object to look up a user's authorities. */ protected 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; } } /** * Query object to look up a user. */ protected 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; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy