我正在尝试将 Spring Security 添加到我的 Spring Boot 应用程序中。我有具有用户和权限的数据库:
CREATE TABLE USERS(
USERNAME TEXT NOT NULL PRIMARY KEY,
PASSWORD TEXT NOT NULL,
ENABLED BOOLEAN NOT NULL
);
CREATE TABLE AUTHORITIES(
USERNAME TEXT REFERENCES USERS(USERNAME),
AUTHORITY TEXT NOT NULL
);
INSERT INTO USERS(USERNAME,PASSWORD,ENABLED)
VALUES ('admin','$2a$10$0eJqlbYcHCD5EyuI0TnuhetVt6p3NDBFXyGtB6D0oigN2mshk2KUu',true);
INSERT INTO AUTHORITIES(USERNAME, AUTHORITY) VALUES('admin','ROLE_ADMIN');
使用简单的 admin:admin 作为凭据。我编写了简单的登录页面,没有什么花哨的只是 Bootstrap 示例:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta name="description" content="login">
<link rel="icon" href="../favicon.ico">
<title>Signin Template for Bootstrap</title>
<!-- Bootstrap core CSS -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="css/signin.css" rel="stylesheet">
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="container">
<form name="loginForm" class="form-signin" action="j_spring_security_check" method='POST'>
<c:if test="${not empty error}">
<div class="alert alert-danger" role="alert">
Invalid username or password!
</div>
</c:if>
<c:if test="${not empty msg}">
<div class="alert alert-success" role="alert">
Logged out successfully!
</div>
</c:if>
<label for="j_username" class="sr-only">Login</label>
<input type="text" id="j_username" class="form-control" placeholder="Login" required autofocus>
<label for="j_password" class="sr-only">Password</label>
<input type="password" id="j_password" class="form-control" placeholder="Password" required>
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
</form>
</div> <!-- /container -->
</body>
</html>
这是我的配置:
package worker.security;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import javax.sql.DataSource;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
DataSource dataSource;
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(SecurityConfig.class);
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/js/**", "/css/**", "/api/**")
.permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.loginProcessingUrl("/j_spring_security_check")
.defaultSuccessUrl("/monitor")
.failureUrl("/login?error")
.usernameParameter("j_username")
.passwordParameter("j_password")
.permitAll()
.and()
.logout()
.logoutSuccessUrl("/login?logout")
.permitAll()
.and()
.csrf().
disable();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource)
.passwordEncoder(passwordEncoder())
.usersByUsernameQuery("select username, password, enabled from users where username=?")
.authoritiesByUsernameQuery("select username, authority from authorities where username=?");
}
@Bean
public PasswordEncoder passwordEncoder() {
PasswordEncoder encoder = new BCryptPasswordEncoder();
return encoder;
}
}
每次尝试登录时都会出现登录错误。我尝试将身份验证更改为内存中,但没有帮助。我启用了 org.spring.security 的登录并得到:
16:09:34.838 [http-nio-8080-exec-4] DEBUG o.s.s.p.JdbcUserDetailsManager(176) - Query returned no results for user ''
16:09:34.955 [http-nio-8080-exec-4] DEBUG o.s.s.a.d.DaoAuthenticationProvider(147) - User '' not found
但是当从命令行执行时,相同的查询会返回所需的行。 有人可以帮忙吗?
最佳答案
好的,我得到了答案,您正在使用 Spring Security 4.x。但在你的 JSP 中,你的 <input>
字段使用 id
命名属性,而不是 name
。只需复制您的 id
值写入 name
一切都应该正常工作。不要丢弃您的id
属性,您的 <label for="...">
仍然需要它们标签。
<input type="text" id="j_username" name="j_username"
class="form-control" placeholder="Login" required autofocus>
<input type="password" id="j_password" name="j_password"
class="form-control" placeholder="Password" required>
关于java - 使用 Spring Security 针对数据库故障进行身份验证。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33569874/