Spring Boot安全性考虑对登录进行大小写不敏感的用户名检查。

9

我正在开发一个Spring Boot Web应用程序。问题出现在登录场景中。假设我有一个以用户名“Ali”注册的用户。这个用户可以使用用户名“Ali”或“ali”登录。下面的代码表示我的Spring安全配置类。似乎在比较时,Spring Boot不检查大写小写因素,但我希望进行检查。

包 nf.something.conf;
import nf.something.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;
// 注册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 在准备好后启用 csrf .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); } }

我还在User类中实现了equals方法:

@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; }
2个回答

3

请尝试修改用户名列:

ALTER TABLE USERS MODIFY username VARCHAR(50) BINARY 

正如我在评论 https://dev59.com/xqPia4cB1Zd3GeqPrwFj#44824164 中所述,我做了类似的事情,问题已经解决了。 - RezKesh

2

正如@dur在评论中所述,我在我的数据库中检查了这些查询:

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

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

他们都返回了相同的结果。所以我更改了我的user表中username列的排序规则,如下所示(之前的排序规则是 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;

现在,列用户名将区分大小写进行检查。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接