Spring boot security consider case insensitive username check for login

I am developing a Spring Boot web application. The problem is in the login script. Suppose I have a user logged in with the username "Ali". This user can either log in with the username "Ali" or "ali". The code below presents my Spring security class. It seems that when comparing, Spring boot does not check uppercase and lowercase, but I want it to be checked.

package ir.saafta.conf;

import ir.saafta.repo.EventRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.security.web.header.writers.StaticHeadersWriter;
import org.springframework.security.web.session.HttpSessionEventPublisher;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import javax.sql.DataSource;

/ **
 * Created by reza on 11/12/16.
 * /
@Configuration
public class SecurityConf extends WebSecurityConfigurerAdapter {

    @Autowired
    private DataSource datasource;
    @Autowired
    private EventRepository eventRepository;

    // Register HttpSessionEventPublisher
    @Bean
    public static ServletListenerRegistrationBean httpSessionEventPublisher () {
        return new ServletListenerRegistrationBean (new HttpSessionEventPublisher ());
    }

    @Override
    protected void configure (HttpSecurity http) throws Exception {
        http.authorizeRequests ()
// .antMatchers (HttpMethod.POST, "/ users /"). permitAll ()
                .antMatchers (HttpMethod.GET, "/ **"). permitAll ()
                .antMatchers (HttpMethod.POST, "/ **"). permitAll ()
                .antMatchers (HttpMethod.PUT, "/ **"). permitAll ()
                .antMatchers (HttpMethod.DELETE, "/ **"). permitAll ()
                .antMatchers ("/ swagger *"). permitAll ()
                //. anyRequest (). permitAll ()
                //. and (). csrf (). disable ();
                .anyRequest (). authenticated ()
                .and (). httpBasic ()
                .and (). formLogin (). successHandler (restAuthenticationSuccessHandler ()). failureHandler (restAuthenticationFailureHandler ())
                .and (). logout (). logoutSuccessHandler (restLogoutSuccessHandler ())
                .and (). exceptionHandling (). authenticationEntryPoint (restAuthenticationEntryPoint ())
                .and (). csrf (). disable (). cors () // TODO enable csrf when we are ready
                .and (). sessionManagement (). maximumSessions (1) .maxSessionsPreventsLogin (true) .sessionRegistry (sessionRegistry ());
        http.headers (). cacheControl (). disable ()
                .addHeaderWriter (new StaticHeadersWriter ("WWW-Authenticate", "xBasic realm = \" fake \ ""));
    }

    @Bean
    public SessionRegistry sessionRegistry () {
        SessionRegistry sessionRegistry = new SessionRegistryImpl ();
        return sessionRegistry;
    }

    @Bean
    public WebMvcConfigurer corsConfigurer () {
        return new WebMvcConfigurerAdapter () {
            @Override
            public void addCorsMappings (CorsRegistry registry) {
                registry.addMapping ("/ **"). allowedOrigins ("*"). allowedMethods ("PUT", "POST", "GET", "DELETE", "HEAD");
            }
        };
    }

    @SuppressWarnings ("SpringJavaAutowiringInspection")
    @Autowired
    public void configureGlobal (AuthenticationManagerBuilder auth, UserDetailsService userDetailsService) throws Exception {
        / * auth
                .jdbcAuthentication (). usersByUsernameQuery ("Select username, password, 'true' as enabled from Users where username =?")
                .authoritiesByUsernameQuery ("select username, authority from authorities where username =?")
                .dataSource (datasource) .passwordEncoder (new BCryptPasswordEncoder ()); * /
        auth.userDetailsService (userDetailsService)
                .passwordEncoder (new BCryptPasswordEncoder ());
    }

    @Bean
    public AuthenticationEntryPoint restAuthenticationEntryPoint () {
        return new RestAuthenticationEntryPoint ();
    }

    @Bean
    public AuthenticationFailureHandler restAuthenticationFailureHandler () {
        return new SimpleUrlAuthenticationFailureHandler ();
    }

    @Bean
    public AuthenticationSuccessHandler restAuthenticationSuccessHandler () {
        return new RESTAuthenticationSuccessHandler (eventRepository);
    }

    @Bean
    public LogoutSuccessHandler restLogoutSuccessHandler () {
        return new RESTLogoutSuccessHandler (eventRepository);
    }
}

I also implemented the method equals

in the class User

:

@Override
    public boolean equals (Object o) {
        if (this == o) return true;
        if (! (o instanceof User)) return false;

        User user = (User) o;

        if (! getUsername (). equals (user.getUsername ())) return false;
        if (getName ()! = null?! getName (). equals (user.getName ()): user.getName ()! = null) return false;
        if (getFamily ()! = null?! getFamily (). equals (user.getFamily ()): user.getFamily ()! = null) return false;
        if (getPassword ()! = null?! getPassword (). equals (user.getPassword ()): user.getPassword ()! = null)
            return false;
        return getMobilePhone ()! = null? getMobilePhone (). equals (user.getMobilePhone ()): user.getMobilePhone () == null;
    }
+3


source to share


2 answers


try changing your username column:



ALTER TABLE USERS MODIFY username VARCHAR(50) BINARY 

      

+1


source


As @dur pointed out in the comments, I checked these queries against my database:

Select username, password, 'true' as enabled 
from Users 
where username = 'Ali'

Select username, password, 'true' as enabled 
from Users 
where username = 'ali'

      

and they both returned the same results. So I changed the column of username

my table collation user

as follows (the previous collation was utf8_general_ci

):



SET FOREIGN_KEY_CHECKS=0;
ALTER TABLE `mydb`.`user`
  CHANGE `username` `username` VARCHAR(50) CHARSET utf8 COLLATE utf8_bin NOT NULL;
SET FOREIGN_KEY_CHECKS=1;

      

The column username

will now be case-sensitive.

0


source







All Articles