Java 如何为自定义SQL架构用户角色配置具有安全性的spring引导?
我尝试将spring引导安全性配置为与我的SQL架构集成:Java 如何为自定义SQL架构用户角色配置具有安全性的spring引导?,java,spring,spring-mvc,spring-boot,spring-security,Java,Spring,Spring Mvc,Spring Boot,Spring Security,我尝试将spring引导安全性配置为与我的SQL架构集成: CREATE TABLE IF NOT EXISTS users ( id SERIAL PRIMARY KEY, username VARCHAR(20) UNIQUE NOT NULL, password VARCHAR(20) UNIQUE NOT NULL, role INTEGER NOT NULL, FOREIGN KEY (role) REFERENCES us
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
username VARCHAR(20) UNIQUE NOT NULL,
password VARCHAR(20) UNIQUE NOT NULL,
role INTEGER NOT NULL,
FOREIGN KEY (role) REFERENCES user_role (id)
);
CREATE TABLE IF NOT EXISTS user_role (
id SERIAL PRIMARY KEY,
role VARCHAR(10)
);
我发现了许多使用spring boot security集成数据库的示例,所有这些示例如下:
@Autowired
public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource)
.usersByUsernameQuery(
"select username,password, enabled from users where username=?")
.authoritiesByUsernameQuery(
"select username, role from user_roles where username=?");
}
我不明白如何使用方法usersByUsernameQuery
和authorities by usernamequery
。为什么全部按用户名选择?密码在哪里?密码不需要进行身份验证
请给我解释一下这是怎么回事。
如何使用configAuthentication()
将我的数据库连接到安全性?根据您的方法,您必须进行一些更改才能成功运行usersByUsernameQuery
和authorities Byusernamequery
中的查询
例如:usersByUsernameQuery
根据您的表定义,应该是选择username,password,true from username=?
,因为您的users表上没有启用字段
而authoritiesByUsernameQuery
应该是select u.username,r.role from users u internal join user\u roles r on(r.id=u.role),其中u.username=?
,因为一个表包含用户信息,而另一个表包含角色,这正是您应该在查询中使用联接的原因
Spring身份验证允许您配置许多实现身份验证方法的方法,在本例中,您提出的问题是jdbc身份验证方法
当您使用jdbc身份验证方法时,有必要检查以下各项:
确保您的pom.xml
具有jdbc依赖项和数据库依赖项,此示例适用于h2数据库
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
然后,您需要创建一个扩展websecurityConfigureAdapter
的类,以便将DataSource
bean注入到AuthenticationManager
builder,这里是Spring身份验证与数据库绑定的地方,以便执行查询以检索您已经在数据库上创建的用户和角色数据
例如:
public class MySecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
DataSource dataSource;
@Autowired
public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {
最后,auth.jdbccauthentication().dataSource(dataSource)
设置数据源以查询用户和角色
前端连接到/login servlet身份验证
首先创建将使用/login
servlet的视图
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://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>
</body>
</html>
希望对您有所帮助。我认为它使用查询获取用户对象。在它拿到它之后。然后进行密码检查。@Imran我也这么想。但是,如果我不知道如何与usersByUsernameQuery
和authorities byusernamequery
交互,如何为我的案例定制它……谢谢您的回答!生成数据源,对我来说不是问题,它已经完成了。问题是我的SQL模式的自定义数据源。我编写auth.jdbccauthentication().dataSource(dataSource)。现在我需要做点什么,但是什么?当我调用.usersByUsernameQuery(…)时,我得到一个异常。我的SQL架构与spring security的预期不匹配。好的,那么您需要知道如何将登录表单连接到身份验证,是吗?第一个登录表单发送用户名和密码值,然后请求通过安全筛选器,此时,spring身份验证将调用您的身份验证生成器,身份验证将通过您在usersByUsernameQuery
和authorities by usernamequery
中定义的查询发送到您的数据库,如果用户存在,则将对其进行身份验证。当然,密码应该匹配才能通过身份验证过程。您是否可以共享一个例外,即获取所有stacktrace以查看错误来自auth.jdbAuthentication().dataSource(dataSource).UsersBySernameQuery的位置(“从用户名=?”的用户中选择用户名、密码、true“+”。authoritiesByUsernameQuery(“从用户中选择user.username、role.role”+“内部加入用户角色启用(user.id=user\u role.user\u id)”+“内部加入角色启用”(role.id=user\u role.role\u id)“+”其中user.username=?”;
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://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>
</body>
</html>
@Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
}
}