Class JdbcDaoImpl

  • All Implemented Interfaces:
    org.springframework.beans.factory.Aware, org.springframework.beans.factory.InitializingBean, org.springframework.context.MessageSourceAware, UserDetailsService
    Direct Known Subclasses:
    JdbcUserDetailsManager

    public class JdbcDaoImpl
    extends org.springframework.jdbc.core.support.JdbcDaoSupport
    implements UserDetailsService, org.springframework.context.MessageSourceAware
    UserDetailsService implementation which retrieves the user details (username, password, enabled flag, and authorities) from a database using JDBC queries.

    Default Schema

    A default database schema is assumed, with two tables "users" and "authorities".

    The Users table

    This table contains the login name, password and enabled status of the user.
    Column
    username
    password
    enabled

    The Authorities Table

    Column
    username
    authority
    If you are using an existing schema you will have to set the queries usersByUsernameQuery and authoritiesByUsernameQuery to match your database setup (see DEF_USERS_BY_USERNAME_QUERY and DEF_AUTHORITIES_BY_USERNAME_QUERY).

    In order to minimise backward compatibility issues, this implementation doesn't recognise the expiration of user accounts or the expiration of user credentials. However, it does recognise and honour the user enabled/disabled column. This should map to a boolean type in the result set (the SQL type will depend on the database you are using). All the other columns map to Strings.

    Group Support

    Support for group-based authorities can be enabled by setting the enableGroups property to true (you may also then wish to set enableAuthorities to false to disable loading of authorities directly). With this approach, authorities are allocated to groups and a user's authorities are determined based on the groups they are a member of. The net result is the same (a UserDetails containing a set of GrantedAuthoritys is loaded), but the different persistence strategy may be more suitable for the administration of some applications.

    When groups are being used, the tables "groups", "group_members" and "group_authorities" are used. See DEF_GROUP_AUTHORITIES_BY_USERNAME_QUERY for the default query which is used to load the group authorities. Again you can customize this by setting the groupAuthoritiesByUsernameQuery property, but the format of the rows returned should match the default.

    • Constructor Summary

      Constructors 
      Constructor Description
      JdbcDaoImpl()  
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      protected void addCustomAuthorities​(java.lang.String username, java.util.List<GrantedAuthority> authorities)
      Allows subclasses to add their own granted authorities to the list to be returned in the UserDetails.
      protected UserDetails createUserDetails​(java.lang.String username, UserDetails userFromUserQuery, java.util.List<GrantedAuthority> combinedAuthorities)
      Can be overridden to customize the creation of the final UserDetailsObject which is returned by the loadUserByUsername method.
      protected java.lang.String getAuthoritiesByUsernameQuery()  
      protected boolean getEnableAuthorities()  
      protected boolean getEnableGroups()  
      protected org.springframework.context.support.MessageSourceAccessor getMessages()  
      protected java.lang.String getRolePrefix()  
      java.lang.String getUsersByUsernameQuery()  
      protected void initDao()  
      protected boolean isUsernameBasedPrimaryKey()  
      protected java.util.List<GrantedAuthority> loadGroupAuthorities​(java.lang.String username)
      Loads authorities by executing the SQL from groupAuthoritiesByUsernameQuery.
      protected java.util.List<GrantedAuthority> loadUserAuthorities​(java.lang.String username)
      Loads authorities by executing the SQL from authoritiesByUsernameQuery.
      UserDetails loadUserByUsername​(java.lang.String username)
      Locates the user based on the username.
      protected java.util.List<UserDetails> loadUsersByUsername​(java.lang.String username)
      Executes the SQL usersByUsernameQuery and returns a list of UserDetails objects.
      void setAuthoritiesByUsernameQuery​(java.lang.String queryString)
      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.
      void setEnableAuthorities​(boolean enableAuthorities)
      Enables loading of authorities (roles) from the authorities table.
      void setEnableGroups​(boolean enableGroups)
      Enables support for group authorities.
      void setGroupAuthoritiesByUsernameQuery​(java.lang.String queryString)
      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.
      void setMessageSource​(org.springframework.context.MessageSource messageSource)  
      void setRolePrefix​(java.lang.String rolePrefix)
      Allows a default role prefix to be specified.
      void setUsernameBasedPrimaryKey​(boolean usernameBasedPrimaryKey)
      If true (the default), indicates the getUsersByUsernameQuery() returns a username in response to a query.
      void setUsersByUsernameQuery​(java.lang.String usersByUsernameQueryString)
      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.
      • Methods inherited from class org.springframework.jdbc.core.support.JdbcDaoSupport

        checkDaoConfig, createJdbcTemplate, getConnection, getDataSource, getExceptionTranslator, getJdbcTemplate, initTemplateConfig, releaseConnection, setDataSource, setJdbcTemplate
      • Methods inherited from class org.springframework.dao.support.DaoSupport

        afterPropertiesSet
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • DEF_USERS_BY_USERNAME_QUERY

        public static final java.lang.String DEF_USERS_BY_USERNAME_QUERY
        See Also:
        Constant Field Values
      • DEF_AUTHORITIES_BY_USERNAME_QUERY

        public static final java.lang.String DEF_AUTHORITIES_BY_USERNAME_QUERY
        See Also:
        Constant Field Values
      • DEF_GROUP_AUTHORITIES_BY_USERNAME_QUERY

        public static final java.lang.String DEF_GROUP_AUTHORITIES_BY_USERNAME_QUERY
        See Also:
        Constant Field Values
      • messages

        protected org.springframework.context.support.MessageSourceAccessor messages
    • Constructor Detail

      • JdbcDaoImpl

        public JdbcDaoImpl()
    • Method Detail

      • getMessages

        protected org.springframework.context.support.MessageSourceAccessor getMessages()
        Returns:
        the messages
      • addCustomAuthorities

        protected void addCustomAuthorities​(java.lang.String username,
                                            java.util.List<GrantedAuthority> authorities)
        Allows subclasses to add their own granted authorities to the list to be returned in the UserDetails.
        Parameters:
        username - the username, for use by finder methods
        authorities - the current granted authorities, as populated from the authoritiesByUsername mapping
      • getUsersByUsernameQuery

        public java.lang.String getUsersByUsernameQuery()
      • initDao

        protected void initDao()
                        throws org.springframework.context.ApplicationContextException
        Overrides:
        initDao in class org.springframework.dao.support.DaoSupport
        Throws:
        org.springframework.context.ApplicationContextException
      • loadUserByUsername

        public UserDetails loadUserByUsername​(java.lang.String username)
                                       throws UsernameNotFoundException
        Description copied from interface: UserDetailsService
        Locates the user based on the username. In the actual implementation, the search may possibly be case sensitive, or case insensitive depending on how the implementation instance is configured. In this case, the UserDetails object that comes back may have a username that is of a different case than what was actually requested..
        Specified by:
        loadUserByUsername in interface UserDetailsService
        Parameters:
        username - the username identifying the user whose data is required.
        Returns:
        a fully populated user record (never null)
        Throws:
        UsernameNotFoundException - if the user could not be found or the user has no GrantedAuthority
      • loadUsersByUsername

        protected java.util.List<UserDetails> loadUsersByUsername​(java.lang.String username)
        Executes the SQL usersByUsernameQuery and returns a list of UserDetails objects. There should normally only be one matching user.
      • loadUserAuthorities

        protected java.util.List<GrantedAuthority> loadUserAuthorities​(java.lang.String username)
        Loads authorities by executing the SQL from authoritiesByUsernameQuery.
        Returns:
        a list of GrantedAuthority objects for the user
      • loadGroupAuthorities

        protected java.util.List<GrantedAuthority> loadGroupAuthorities​(java.lang.String username)
        Loads authorities by executing the SQL from groupAuthoritiesByUsernameQuery.
        Returns:
        a list of GrantedAuthority objects for the user
      • createUserDetails

        protected UserDetails createUserDetails​(java.lang.String username,
                                                UserDetails userFromUserQuery,
                                                java.util.List<GrantedAuthority> combinedAuthorities)
        Can be overridden to customize the creation of the final UserDetailsObject which is returned by the loadUserByUsername method.
        Parameters:
        username - the name originally passed to loadUserByUsername
        userFromUserQuery - the object returned from the execution of the
        combinedAuthorities - the combined array of authorities from all the authority loading queries.
        Returns:
        the final UserDetails which should be used in the system.
      • setAuthoritiesByUsernameQuery

        public void setAuthoritiesByUsernameQuery​(java.lang.String queryString)
        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 DEF_AUTHORITIES_BY_USERNAME_QUERY; when modifying this query, ensure that all returned columns are mapped back to the same column positions as in the default query.
        Parameters:
        queryString - The SQL query string to set
      • getAuthoritiesByUsernameQuery

        protected java.lang.String getAuthoritiesByUsernameQuery()
      • setGroupAuthoritiesByUsernameQuery

        public void setGroupAuthoritiesByUsernameQuery​(java.lang.String queryString)
        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 DEF_GROUP_AUTHORITIES_BY_USERNAME_QUERY; when modifying this query, ensure that all returned columns are mapped back to the same column positions as in the default query.
        Parameters:
        queryString - The SQL query string to set
      • setRolePrefix

        public void setRolePrefix​(java.lang.String rolePrefix)
        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 Spring Security classes, in the case that the prefix is not already present in the db.
        Parameters:
        rolePrefix - the new prefix
      • getRolePrefix

        protected java.lang.String getRolePrefix()
      • setUsernameBasedPrimaryKey

        public void setUsernameBasedPrimaryKey​(boolean usernameBasedPrimaryKey)
        If true (the default), indicates the 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 loadUserByUsername(String) derived username in the returned UserDetails.
        Parameters:
        usernameBasedPrimaryKey - true if the mapping queries return the username String, or false if the mapping returns a database primary key.
      • isUsernameBasedPrimaryKey

        protected boolean isUsernameBasedPrimaryKey()
      • setUsersByUsernameQuery

        public void setUsersByUsernameQuery​(java.lang.String usersByUsernameQueryString)
        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 DEF_USERS_BY_USERNAME_QUERY; when modifying this query, ensure that all returned columns are mapped back to the same column positions as in the 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
         "select username,password,'true' as enabled from users where username = ?"
         
        Parameters:
        usersByUsernameQueryString - The query string to set
      • getEnableAuthorities

        protected boolean getEnableAuthorities()
      • setEnableAuthorities

        public void setEnableAuthorities​(boolean enableAuthorities)
        Enables loading of authorities (roles) from the authorities table. Defaults to true
      • getEnableGroups

        protected boolean getEnableGroups()
      • setEnableGroups

        public void setEnableGroups​(boolean enableGroups)
        Enables support for group authorities. Defaults to false
        Parameters:
        enableGroups -
      • setMessageSource

        public void setMessageSource​(org.springframework.context.MessageSource messageSource)
        Specified by:
        setMessageSource in interface org.springframework.context.MessageSourceAware