Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ignore username's case in SpringSecurity

Does SpringSecurity have some built-in ability to ignore the letter-case of username? For example, if the username is "student001", then it will accept "Student001" as well as "stUdent001".

The reason I need this is that our system use emails as usernames. Of course I would be able to do this by extending the DAOAuthenticationProvider class, but I just wonder if there's any built-in option exists for this problem?

like image 917
Hoàng Long Avatar asked Jun 07 '12 04:06

Hoàng Long


3 Answers

If you're using the DaoAuthenticationProvider then I presume you're using the JdbcDaoImpl with it, which loads users from a JDBC database.

If so, you can override the SQL query that JdbcDaoImpl uses to look up users by manually creating the bean yourself. The default query that Spring Security uses is:

select username,password,enabled from users where username = ?

You can use the SQL lower function to ignore case:

select username,password,enabled from users where lower(username) = lower(?)

The appropriate Spring Security XML configuration is:

<bean id="org.springframework.security.authenticationManager" class="org.springframework.security.authentication.ProviderManager">
    <property name="providers">
        <list>
            <ref bean="daoAuthenticationProvider"/>
        </list>
    </property>
</bean>

<bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
    <property name="userDetailsService" ref="caseInsensitiveUserDetailsService"/>
</bean>

<bean id="caseInsensitiveUserDetailsService" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
    <property name="usersByUsernameQuery" value="select username, password, enabled from users where lower(username) = lower(?)" />
</bean>
like image 149
gutch Avatar answered Oct 16 '22 12:10

gutch


I believe any authentication provider take advantage of the UserDetails and UserDetailsService interfaces.

When an implementation of

UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;

is given for custom application specific UserDetailsService, we can ignore the case of username and provide the UserDetails to the spring-security to proceed with further authentication/authorization.

BUT, if spring provided org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl is used as UserDetailsService it will load the userdetails from user table with condition "where username=?". So it is case-sensitive.

like image 4
Ahamed Mustafa M Avatar answered Oct 16 '22 10:10

Ahamed Mustafa M


gutch is partially right. It allows user with JdbcDaoImpl does case-insensitive check with user table. But you will require Authorities table query also needs to be changed.

<bean id="caseInsensitiveUserDetailsService" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
    <property name="usersByUsernameQuery" value="select username, password, enabled from users where lower(username) = lower(?)" />
    <property name="authoritiesByUsernameQuery" value="select username,authority " +
        "from authorities where lower(username) = lower(?)" />
</bean>
like image 1
agent_daemon Avatar answered Oct 16 '22 10:10

agent_daemon