配置 Spring Web 安全登录后给我无效的用户名和密码错误

Posted

技术标签:

【中文标题】配置 Spring Web 安全登录后给我无效的用户名和密码错误【英文标题】:After configuring Spring Web security login gives me Invalid username and password error 【发布时间】:2021-07-07 12:37:02 【问题描述】:

配置 Spring 的网络安全后,我的注册工作正常,但是当我尝试登录时,我的登录页面显示我的用户名或密码无效,我在内存 h2 数据库中使用,如果我输入正确,我在注册后检查数据库值(用户名密码)。当我在 UserDetail 服务中使用硬编码值时,登录工作正常

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter 
    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http
                .authorizeRequests()
                .antMatchers("/", "/home", "/h2-console/**", "/register", "/users")
                .permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
                .logout()
                .permitAll();
        //ovo popravlja problem whitelabel error kod pritiska na gumb
        http
                .headers().frameOptions().sameOrigin();
        http
                .csrf().disable();
        http
                .headers().frameOptions().disable();
    

    @Autowired
    DataSource dataSource;

    @Autowired
    protected void configure(final AuthenticationManagerBuilder auth) throws Exception 
        auth.jdbcAuthentication().dataSource(dataSource);
    

Sql 数据库:

DROP TABLE IF EXISTS employee;
DROP TABLE IF EXISTS authorities;
DROP TABLE IF EXISTS users;



create table users (
                       id INT AUTO_INCREMENT PRIMARY KEY,
                       username varchar(50) not null ,
                       email varchar(120),
                       password varchar(255) not null,
                       enabled boolean
);

create table authorities (
                             username varchar(50) not null,
                             authority varchar(50) not null,
                             foreign key (username) references users (username)
);

春季开机日志:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.4.4)

2021-04-12 14:12:04.739  INFO 17532 --- [           main] com.m2.cfg.TestApplication               : Starting TestApplication using Java 15 on DESKTOP-EFU4KH0 with PID 17532 (C:\Users\Tome\Downloads\spring-security-jpa-master\mc2-test\target\classes started by Tome in C:\Users\Tome\Downloads\spring-security-jpa-master\mc2-test)
2021-04-12 14:12:04.745  INFO 17532 --- [           main] com.m2.cfg.TestApplication               : No active profile set, falling back to default profiles: default
2021-04-12 14:12:05.893  INFO 17532 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2021-04-12 14:12:05.961  INFO 17532 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 56 ms. Found 1 JPA repository interfaces.
2021-04-12 14:12:06.578  INFO 17532 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2021-04-12 14:12:06.588  INFO 17532 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2021-04-12 14:12:06.588  INFO 17532 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.44]
2021-04-12 14:12:06.751  INFO 17532 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2021-04-12 14:12:06.751  INFO 17532 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1908 ms
2021-04-12 14:12:06.804  INFO 17532 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2021-04-12 14:12:06.922  INFO 17532 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2021-04-12 14:12:06.929  INFO 17532 --- [           main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
2021-04-12 14:12:07.111  INFO 17532 --- [           main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
2021-04-12 14:12:07.159  INFO 17532 --- [           main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 5.4.29.Final
2021-04-12 14:12:07.278  INFO 17532 --- [           main] o.hibernate.annotations.common.Version   : HCANN000001: Hibernate Commons Annotations 5.1.2.Final
2021-04-12 14:12:07.399  INFO 17532 --- [           main] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
2021-04-12 14:12:07.550  INFO 17532 --- [           main] o.hibernate.id.enhanced.TableGenerator   : HHH000398: Explicit segment value for id generator [hibernate_sequences.sequence_name] suggested; using default [default]
2021-04-12 14:12:07.958  INFO 17532 --- [           main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
2021-04-12 14:12:07.971  INFO 17532 --- [           main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2021-04-12 14:12:08.113  WARN 17532 --- [           main] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2021-04-12 14:12:08.573  INFO 17532 --- [           main] o.s.s.web.DefaultSecurityFilterChain     : Will secure any request with [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@43df1377, org.springframework.security.web.context.SecurityContextPersistenceFilter@7f64bd7, org.springframework.security.web.header.HeaderWriterFilter@5badeda0, org.springframework.security.web.authentication.logout.LogoutFilter@2ba318c2, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@67c2b55d, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@746fd19b, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@7a587e84, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@1cee3e05, org.springframework.security.web.session.SessionManagementFilter@1dd247b, org.springframework.security.web.access.ExceptionTranslationFilter@40b01718, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@565a6af]
2021-04-12 14:12:08.749  INFO 17532 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2021-04-12 14:12:09.040  INFO 17532 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2021-04-12 14:12:09.057  INFO 17532 --- [           main] com.m2.cfg.TestApplication               : Started TestApplication in 5.008 seconds (JVM running for 6.678)
2021-04-12 14:12:13.285  INFO 17532 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2021-04-12 14:12:13.285  INFO 17532 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2021-04-12 14:12:13.286  INFO 17532 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
2021-04-12 14:12:13.490  WARN 17532 --- [nio-8080-exec-1] o.a.c.util.SessionIdGeneratorBase        : Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [145] milliseconds.
h2 数据库值

注册包含PasswordEncoder @Bean的Controller类,并将对象写入内存数据库中的h2:

@Controller
public class RegisterController 

    @Bean
    public PasswordEncoder encoder() 
        return new BCryptPasswordEncoder();
    

    @Autowired
    private UserRepository userRepository;
    @Autowired
    private PasswordEncoder passwordEncoder;

    @RequestMapping("/register")
    public String read(@ModelAttribute(name = "user") Users user, Model model) 

        if(user.getUsername() != null && user.getEmail() != null && user.getPass() != null)
        
            var u1 = new Users(user.getUsername(), user.getEmail(), passwordEncoder.encode(user.getPass()));
            userRepository.save(u1);
        
        return "register";
    

和登录html代码:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org"
      xmlns:sec="https://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
    <title>Spring Security Example </title>
</head>
<body>
<div th:if="$param.error">
    Invalid username and password.
</div>
<div th:if="$param.logout">
    You have been logged out.
</div>
<form th:action="@/login" method="post">
    <div><label> User Name : <input type="text" name="username"/> </label></div>
    <div><label> Password: <input type="password" name="password"/> </label></div>
    <div><input type="submit" value="Sign In"/></div>
</form>
<br>
<a href="register.html">register</a>
</body>
</html>

用户存储库:

package com.m2.cfg.repository;

import com.m2.cfg.domain.Users;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UserRepository
        extends CrudRepository<Users, Integer> 
    Users findByUsername(String username);

【问题讨论】:

您的文件中是否有一个PasswordEncoder bean 尚未共享?您在数据库中的密码看起来是使用 BCrypt 编码的,这意味着您的应用程序需要知道才能使用 BCrypt 比较密码。 @EleftheriaStein-Kousathana 我该怎么做? “对应用程序说它需要与 BCrypt 进行比较”......但另一方面,我尝试使用硬编码用户插入查询,这样密码将直接写入数据库而不加密,然后我会在日志中收到密码不加密的消息看起来它使用 BCrypt,我会在页面上收到错误的用户名/密码错误 似乎没有告诉 Spring Security 使用UserRepository。与其直接访问存储库,不如尝试公开一个UserDetailsManager Bean。它只会返回return new JdbcUserDetailsManager(dataSource);。然后在您的控制器中自动连接 UserDetailsManager 而不是存储库并调用 userDetailsManager.createUser(u1) 来保存用户。 但用户按预期保存在数据库中,这只是尝试登录时验证的问题 我担心 Spring Security 不知道它应该从该特定数据库表中检索用户。创建一个访问数据库表的UserDetailsManager会让Spring Security知道。 【参考方案1】:

移动

@Bean
public PasswordEncoder encoder() 
    return new BCryptPasswordEncoder();

WebSecurityConfig 类。

【讨论】:

有关系吗?是不是任何用@Bean 注释的东西都会首先被注册并在任何需要的地方提取,而不管文件是什么? 恕我直言,它仅适用于 @Configuration 类 这不是问题......我也认为问题在于比较散列密码和平面密码,但我出于测试目的删除了所有加密,它仍然无法正常工作【参考方案2】:

看看你的WebSecurityConfig。没有配置PasswordEncoder。 由于输入的密码在未编码状态下进行比较,因此显示无效消息。

PasswordEncoder bean 移动到WebSecurityConfig 并配置PasswordEncoder,如下所示。


@Bean
public PasswordEncoder encoder() 
    return new BCryptPasswordEncoder();


@Autowired
protected void configure(final AuthenticationManagerBuilder auth) throws Exception 
    auth.jdbcAuthentication()
        .dataSource(dataSource)
        .passwordEncoder(encoder());

【讨论】:

这不是问题,因为我尝试使用硬编码值并将值直接插入密码字段而没有加密,但它仍然没有工作...... @TomeVersic 要使用jdbcAuthenticationusers 表中必须有enable 列。但是当我查看您的 h2 数据库图像时,没有 enable 列。请检查一下。如果不是这样,我也想上传错误日志。 用户表中启用的列看起来更好

以上是关于配置 Spring Web 安全登录后给我无效的用户名和密码错误的主要内容,如果未能解决你的问题,请参考以下文章

Spring 4 安全、MySQL、c3p0 连接。登录在 Spring 5 中有效,但在 Spring 4 中无效

使 Spring 安全会话无效

使会话弹簧安全性无效

LDAP Spring 安全登录处理 URL 302 错误

Spring Security - 公共页面重定向到使用无效会话 ID 登录

Spring安全登录错误页面,访问被拒绝