spring - SpringBoot:Imp SpringSecurity:使用用户/密码登录时出现屏幕错误消息“用户已禁用”
问题描述
我刚刚开始实施 SpringSecurity 但登录后在屏幕上收到错误消息“用户已禁用”
默认情况下它工作得很好。在使用 /user 或 /admin 并尝试登录时显示“用户已禁用”
我正在执行以下步骤:
首先创建 schema.sql(在资源文件夹下)
CREATE TABLE USERS ( USERNAME VARCHAR(128) PRIMARY KEY, PASSWORD VARCHAR(128) NOT NULL, ENABLED CHAR(1) CHECK (ENABLED IN ('Y','N') ) NOT NULL ); CREATE TABLE AUTHORITIES ( USERNAME VARCHAR(128) NOT NULL, AUTHORITY VARCHAR(128) NOT NULL ); ALTER TABLE AUTHORITIES ADD CONSTRAINT AUTHORITIES_UNIQUE UNIQUE (USERNAME, AUTHORITY); ALTER TABLE AUTHORITIES ADD CONSTRAINT AUTHORITIES_FK1 FOREIGN KEY (USERNAME) REFERENCES USERS (USERNAME);
在资源文件夹下创建“data.sql”
insert into USERS(USERNAME,PASSWORD,ENABLED) VALUES ('user','pass','Y'); insert into USERS(USERNAME,PASSWORD,ENABLED) VALUES ('admin','pass','Y'); insert into AUTHORITIES (USERNAME,AUTHORITY) values ('user','ROLE_USER'); insert into AUTHORITIES (USERNAME,AUTHORITY) values ('admin','ROLE_ADMIN');
HomeResource.JAVA(这是一个控制器类 API)
package com.example.callCenter; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HomeResource{ @GetMapping("/") public String home(){ return("<h1>Welcome home page..</h1>"); } @GetMapping("/user") public String user() { return ("<h1>Welcome User page</h1>"); } @GetMapping("/admin") public String admin() { return("<h1>Welcome Admin page</h1>"); } }
SecurityConfiguration.java(这是启用 Spring Form PAGE)
package com.example.callCenter; import javax.sql.DataSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; 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.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.User; import org.springframework.security.crypto.password.NoOpPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; @EnableWebSecurity public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Autowired DataSource dataSource; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.jdbcAuthentication().dataSource(dataSource) .usersByUsernameQuery("select username,password,enabled " + "from users " + "where username = ?") .authoritiesByUsernameQuery("select username,AUTHORITY " + "from AUTHORITIES " + "where username = ?"); // This beloe code is default implementation with MySQL database // auth.jdbcAuthentication() // .dataSource(dataSource) // .withDefaultSchema() // .withUser( // User.withUsername("user") // .password("pass") // .roles("USER") // ) // .withUser( // User.withUsername("admin") // .password("pass") // .roles("ADMIN") // ); } @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .authorizeRequests() .antMatchers("/admin").hasRole("ADMIN") .antMatchers("/user").hasAnyRole("ADMIN","USER") .antMatchers("/").permitAll() .and().formLogin(); } @Bean public PasswordEncoder getPasswordEncoder() { return NoOpPasswordEncoder.getInstance(); } }
调用应用程序.java
package com.example.callCenter; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class CallApplication { public static void main(String[] args) { SpringApplication.run(CallCenterApplication.class, args); } }
pom.xml :由于表单正在打开,因此所有依赖项都不是问题
应用程序属性:
spring.datasource.url= spring.datasource.username= spring.datasource.password= spring.datasource.driverClassName= spring.jpa.show_sql=true spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.SQLServer2012Dialect spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl spring.jpa.hibernate.ddl-auto=update spring.jpa.hibernate.dialect=org.hibernate.dialect.SQLServer2012Dialect spring.jpa.format_sql=true
我添加了几乎所有细节,我这边没有任何待处理的内容,但现在我需要一些帮助,为什么它不允许我打电话给用户并允许我登录。
解决方案
这里的问题是存储在列中的值
ENABLED CHAR(1) CHECK (ENABLED IN ('Y','N') ) NOT NULL
JdbcUserDetailsManager。loadUsersByUsername(String username)在创建 User 对象时具有以下代码逻辑来填充其属性。
String userName = rs.getString(1);
String password = rs.getString(2);
boolean enabled = rs.getBoolean(3);
要获得enabled
状态, 使用ResultSet.getBoolean()并且相同的 java 文档提到以下内容
检索此 ResultSet 对象的当前行中指定列的值,作为 Java 编程语言中的布尔值。
如果指定列的数据类型为 CHAR 或 VARCHAR 且包含“0”,或者数据类型为 BIT、TINYINT、SMALLINT、INTEGER 或 BIGINT 且包含 0,则返回 false 值。如果指定列的数据类型为 CHAR 或 VARCHAR 且包含“1”,或者数据类型为 BIT、TINYINT、SMALLINT、INTEGER 或 BIGINT 且包含 1,则返回值 true。
在上面的代码中,启用/禁用的正确值分别是“1”和“0”。
推荐阅读
- java - 使用 JVM 参数在 jar 应用程序中运行 java
- python - 当 Python 对象的引用计数达到零时,注册清理的最可靠方法是什么?
- python-3.x - 如何在 Python3 中将 Azure URI 解析为键值对?
- c++ - libcurl C++:多路复用时检索 HTTP 响应代码
- html - 为什么在这个 flex-column 方向示例中 height 属性会覆盖 flex-basis
- javascript - React Native如何从firebase获取后台消息
- javascript - React Native:照片不会上传到 Firebase?
- nlp - 聚类数据和 KMeans 聚类中心的标签
- python - 熊猫条件格式:突出显示一帧中的单元格与另一帧中的单元格不相等
- python - 在python中遍历JSON文件