当前位置: 首页 > 知识库问答 >
问题:

spring boot安全考虑对登录不区分大小写的用户名检查

席乐童
2023-03-14

我正在开发一个spring boot网络应用程序。问题出在登录场景中。假设我有一个用户名为“阿里”注册的用户。此用户可以使用用户名“ali”或“ali”登录。下面的代码表示我的spring安全配置类。似乎在比较时,spring boot没有检查大小写因子,但我希望它被检查。

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);
    }
}

我还在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个答案

孙鑫鹏
2023-03-14

正如@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;

现在,列username将被检查为区分大小写。

云开诚
2023-03-14

请您尝试更改用户名:

ALTER TABLE USERS MODIFY username VARCHAR(50) BINARY 
 类似资料:
  • 我正在使用AWS Cognito来管理我的web应用程序的用户注册和用户访问。具体来说,我使用的是Cognito托管的UI。这意味着Cognito为我的用户提供了一个要注册的UI,我无权修改我的应用程序的用户注册或登录页面(Cognito提供的控件除外)。我使用电子邮件地址作为用户名,因此新用户只需提供电子邮件地址和密码。 Cognito将电子邮件地址视为区分大小写。如果用户使用电子邮件地址JOH

  • 本文向大家介绍C# WinForm 登录界面的图片验证码(区分大小写+不区分大小写),包括了C# WinForm 登录界面的图片验证码(区分大小写+不区分大小写)的使用技巧和注意事项,需要的朋友参考一下 一、功能界面 图1 验证码(区分大小写) 图2 验证码(不区分大小写) 二、创建一个产生验证码的类Class1 (1)生成随机验证码字符串,用的是Random随机函数 (2)创建验证码图片,将该字

  • 问题内容: 我正在尝试提出一个要求区分大小写的结果的请求。 例如在我的数据库中 该请求是 但我有3行作为结果,我只想要abcdef 我试图找到一个解决方案 但是我有这个错误: 未知归类:’Latin1_General_CS_AS’{“成功”:false,“错误”:“#1273-未知归类:’Latin1_General_CS_AS’”} 谢谢 问题答案: 感谢您的帮助,我找到了不是latin1 ut

  • 问题内容: 我有一个Lucene索引,该索引当前区分大小写。我想添加的 选项 有不区分大小写作为后备的。这意味着与案例匹配的结果将获得更大的权重,并且将首先出现。例如,如果结果数限制为10,并且有10个匹配项符合我的情况,那就足够了。如果仅找到7个结果,则可以从不区分大小写的搜索中再添加3个结果。 我的案子实际上更复杂,因为我有不同重量的物品。理想情况下,匹配“错误”的表壳会增加一些重量。不用说,

  • 对于报告(0.1%的所有查询),我需要返回一个所有可能类别的列表,区分大小写! 考虑以下文件: 运行以下查询: 返回: 是否有方法返回区分大小写的类别(存储在文档中)?我对此查询结果中的感兴趣。 Elasticsearch论坛中的问题 谢谢,伊泰