Spring Security是Spring Framework的一个模块,用于提供身份验证、授权、攻击防护等安全相关功能。Spring Security支持多种存储用户数据的方式,包括内存、JDBC、LDAP等,其中存储到数据库是最常用的方式之一。
下面给出Spring Security将用户数据存储到数据库的完整攻略,主要包含以下步骤:
1. 引入Spring Security依赖
在项目的pom.xml中添加Spring Security的依赖:
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>5.5.1</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>5.5.1</version>
</dependency>
2. 创建用户表
Spring Security默认使用以下表结构存储用户数据:
CREATE TABLE users(
username VARCHAR(50) PRIMARY KEY,
password VARCHAR(100) NOT NULL,
enabled BOOLEAN NOT NULL
);
CREATE TABLE authorities (
username VARCHAR(50) NOT NULL,
authority VARCHAR(50) NOT NULL,
CONSTRAINT fk_authorities_users FOREIGN KEY(username) REFERENCES users(username)
);
CREATE UNIQUE INDEX ix_auth_username
ON authorities(username,authority);
其中,users表用于存储用户名、密码、是否激活等信息,authorities表用于存储用户名和角色信息。
可以根据实际需求修改表结构。
3. 编写数据访问层代码
在Spring Security中,需要实现UserDetailsService接口来获取用户信息。可以通过JDBC、MyBatis、Hibernate等方式访问数据库,并实现UserDetailsService接口。
下面是通过JDBC访问数据库的示例:
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class JdbcUserDetailsService implements UserDetailsService {
private final DataSource dataSource;
public JdbcUserDetailsService(DataSource dataSource) {
this.dataSource = dataSource;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
String sql = "SELECT username,password,enabled FROM users WHERE username=?";
Connection conn = null;
try {
conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, username);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
String password = rs.getString("password");
boolean enabled = rs.getBoolean("enabled");
String roleSql = "SELECT authority FROM authorities WHERE username=?";
PreparedStatement rolePs = conn.prepareStatement(roleSql);
rolePs.setString(1, username);
ResultSet roleRs = rolePs.executeQuery();
List<SimpleGrantedAuthority> authorities = new ArrayList<>();
while (roleRs.next()) {
String authority = roleRs.getString("authority");
SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(authority);
authorities.add(simpleGrantedAuthority);
}
return new User(username, password, enabled, true, true, true, authorities);
} else {
throw new UsernameNotFoundException("User not found with username: " + username);
}
} catch (SQLException e) {
throw new UsernameNotFoundException("Error reading user data", e);
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
在这个示例中,我们通过DataSource获取Connection对象,然后执行查询SQL语句获取用户信息和角色信息。最后返回一个UserDetails对象,表示当前用户的详细信息。
4. 配置Spring Security
在Spring Security中配置UserDetailsService的实现类,并指定加密算法:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
JdbcUserDetailsService userDetailsService = new JdbcUserDetailsService(dataSource);
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/user/**").hasRole("USER")
.anyRequest().permitAll()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/index")
.permitAll()
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/login")
.permitAll()
.and()
.csrf()
.disable();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
在这个示例中,我们配置了两个权限:ADMIN和USER,分别对应不同的URL模式。在configure方法中,我们配置了登录页、登出URL、成功跳转页面等相关信息。
小结
通过以上步骤,我们可以将Spring Security的用户数据存储到数据库中。只需要实现UserDetailsService接口,读取数据库中的数据即可。
示例代码可以参考Spring官方文档的示例代码:jbc-authentication 和 jpa-authentication。这两个示例分别演示了通过JDBC和JPA方式读取数据库中用户数据的方法。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Security将用户数据存储到数据库的方法 - Python技术站