Spring Security登录失败

huangapple go评论75阅读模式
英文:

Spring Security login failed

问题

使用定制数据源和Spring Security密码编码器,但登录失败。
Spring Boot版本为2.7.0。
我首先注册了一个名为"132456"的用户,密码为"123456",然后尝试登录,但失败了。
然后我创建了一个测试类:打印true。

    @Test
    public void selectTest() {
        UserDetails userDetails = userInfoService.loadUserByUsername("123456");
        System.out.println(userDetails);
        boolean matches = passwordEncoder.matches("123456", userDetails.getPassword());
        System.out.println(matches);
    }

Spring Security配置

@EnableWebSecurity
@Configuration
@Slf4j
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfiguration {

    @Autowired
    UserInfoService userInfoService;

    @Autowired
    Gson gson;

    @Autowired
    JwtTokenFilter jwtTokenFilter;

    @Autowired
    PasswordEncoder passwordEncoder;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        .... 登录URL已经通过
        http.formLogin().loginProcessingUrl("/api/login").permitAll()
                .successHandler((request, response, authentication) -> {
                    this.sendMessage(response, authentication);
                })
                .failureHandler((request, response, exception) ->
                        jwtTokenFilter.sendError(response, HttpServletResponse.SC_UNAUTHORIZED, "用户名或密码错误"));
        http.logout().invalidateHttpSession(true).clearAuthentication(false);
        http.rememberMe().disable();
        http.csrf().disable();
        return http.build();
    }
    
    @Bean
    DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(userInfoService);
        authProvider.setPasswordEncoder(passwordEncoder);
        return authProvider;
    }

}

userServiceImpl

// 使用mybatisplus框架
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

    @Autowired
    PasswordEncoder passwordEncoder;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserInfo::getUsername, username);
        return getOne(queryWrapper);
    }

    @Override
    public boolean create(UserInfoDTO userInfoDTO) {
        userInfoDTO.setPassword(passwordEncoder.encode(userInfoDTO.getPassword()));
        return save(BeanUtil.copyProperties(userInfoDTO, UserInfo.class));
    }
}

登录成功后,返回令牌。

英文:

Use customized datasource and Spring Security password encoder, but login failed.
Spring Boot version 2.7.0
I first register a user named "132456", passsword "123456", then login, but failed;
Then I create a test class: print true

    @Test
    public void selectTest() {
        UserDetails userDetails = userInfoService.loadUserByUsername(&quot;123456&quot;);
        System.out.println(userDetails);
        boolean matches = passwordEncoder.matches(&quot;123456&quot;, userDetails.getPassword());
        System.out.println(matches);
    }

Spring Security config

@EnableWebSecurity
@Configuration
@Slf4j
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfiguration {

    @Autowired
    UserInfoService userInfoService;

    @Autowired
    Gson gson;

    @Autowired
    JwtTokenFilter jwtTokenFilter;

    @Autowired
    PasswordEncoder passwordEncoder;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        .... login url has pass
        http.formLogin().loginProcessingUrl(&quot;/api/login&quot;).permitAll()
                .successHandler((request, response, authentication) -&gt; {
                    this.sendMessage(response, authentication);
                })
                .failureHandler((request, response, exception) -&gt;
                        jwtTokenFilter.sendError(response, HttpServletResponse.SC_UNAUTHORIZED, &quot;username or password error&quot;));
        http.logout().invalidateHttpSession(true).clearAuthentication(false);
        http.rememberMe().disable();
        http.csrf().disable();
        return http.build();
    }
    
    @Bean
    DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
        authProvider.setUserDetailsService(userInfoService);
        authProvider.setPasswordEncoder(passwordEncoder);
        return authProvider;
    }

}

userServiceImpl

// use mybatisplus framework
@Service
public class UserInfoServiceImpl extends ServiceImpl&lt;UserInfoMapper, UserInfo&gt; implements UserInfoService {

    @Autowired
    PasswordEncoder passwordEncoder;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        LambdaQueryWrapper&lt;UserInfo&gt; queryWrapper = new LambdaQueryWrapper&lt;&gt;();
        queryWrapper.eq(UserInfo::getUsername, username);
        return getOne(queryWrapper);
    }

    @Override
    public boolean create(UserInfoDTO userInfoDTO) {
        userInfoDTO.setPassword(passwordEncoder.encode(userInfoDTO.getPassword()));
        return save(BeanUtil.copyProperties(userInfoDTO, UserInfo.class));
    }
}

login success, then return token.

答案1

得分: 1

Omg,我忘了覆盖接口UserDetails内部方法:isEnabled(),哈哈哈。花了两个小时找到这个错误。

/**
 * 指示用户是否已启用或禁用。禁用的用户无法进行身份验证。
 * @return 如果用户已启用,则返回&lt;code&gt;true&lt;/code&gt;,否则返回&lt;code&gt;false&lt;/code&gt;
 */
boolean isEnabled();
英文:

Omg, I forgot to override the interface UserDetails inner method: isEnabled(), Hahahah. Spent two hours finding this bug.

/**
 * Indicates whether the user is enabled or disabled. A disabled user cannot be
 * authenticated.
 * @return &lt;code&gt;true&lt;/code&gt; if the user is enabled, &lt;code&gt;false&lt;/code&gt; otherwise
 */
boolean isEnabled();

huangapple
  • 本文由 发表于 2023年7月3日 19:49:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/76604459.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定