Spring Security系列之入门
·
Spring Security 快速入门
- 引入依赖
- 如果使用Maven,在
pom.xml文件中添加Spring Security依赖。对于Spring Boot项目:
- 如果使用Maven,在
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring - boot - starter - security</artifactId>
</dependency>
- 如果是普通Spring项目,还需要添加Spring Security相关的核心依赖和Web相关依赖等。
- 简单配置
- 创建一个配置类,继承
WebSecurityConfigurerAdapter,用于配置Spring Security。
- 创建一个配置类,继承
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
@Bean
@Override
public UserDetailsService userDetailsService() {
UserDetails user =
User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build();
UserDetails admin =
User.withDefaultPasswordEncoder()
.username("admin")
.password("admin")
.roles("ADMIN")
.build();
return new InMemoryUserDetailsManager(user, admin);
}
}
- 在上述配置中:
configure(HttpSecurity http)方法定义了访问规则。/和/home路径允许所有用户访问,其他路径需要认证。formLogin()配置了基于表单的登录,loginPage("/login")指定了登录页面路径,并且允许所有用户访问登录页面。logout()配置了注销功能,允许所有用户访问注销路径。userDetailsService()方法在内存中创建了两个用户user和admin,并为其分配了角色。
- 创建登录和页面
- 创建一个简单的
login.html作为登录页面:
- 创建一个简单的
<!DOCTYPE html>
<html lang="zh - CN">
<head>
<meta charset="UTF - 8">
<title>登录</title>
</head>
<body>
<form action="/login" method="post">
<label for="username">用户名:</label>
<input type="text" id="username" name="username" required><br>
<label for="password">密码:</label>
<input type="password" id="password" name="password" required><br>
<input type="submit" value="登录">
</form>
</body>
</html>
- 创建一个
home.html作为登录成功后的页面:
<!DOCTYPE html>
<html lang="zh - CN">
<head>
<meta charset="UTF - 8">
<title>首页</title>
</head>
<body>
<h1>欢迎登录</h1>
</body>
</html>
- 启动应用
- 启动Spring Boot应用(如果是Spring Boot项目)或部署到应用服务器(如Tomcat等)。访问应用,未登录时会被重定向到登录页面,输入正确的用户名和密码后可访问受保护的资源。
Spring Security 高级应用
- 自定义认证逻辑
- 实现
UserDetailsService接口,从数据库或其他数据源加载用户信息。
- 实现
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// 从数据库中查询用户信息
User user = userRepository.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("用户不存在");
}
// 将用户信息转换为Spring Security的UserDetails
return org.springframework.security.core.userdetails.User.withDefaultPasswordEncoder()
.username(user.getUsername())
.password(user.getPassword())
.roles(user.getRole())
.build();
}
}
- 在配置类中使用自定义的
UserDetailsService:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailsService customUserDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
// 配置其他安全规则
}
@Override
@Bean
public UserDetailsService userDetailsService() {
return customUserDetailsService;
}
}
- 基于角色和权限的授权
- 在配置类的
configure(HttpSecurity http)方法中细化授权规则。例如,只有具有ADMIN角色的用户才能访问特定的管理页面:
- 在配置类的
http
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/user/**").hasAnyRole("USER", "ADMIN")
.anyRequest().authenticated();
- 也可以基于权限进行授权,在数据库中为用户分配具体的权限,然后在配置中使用
hasAuthority方法进行判断。
- OAuth2集成
- 引入OAuth2相关依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring - boot - starter - oauth2 - client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring - boot - starter - oauth2 - resource - server</artifactId>
</dependency>
- 配置OAuth2客户端,例如配置GitHub登录:
spring:
security:
oauth2:
client:
registration:
github:
client - id: your - github - client - id
client - secret: your - github - client - secret
scope: read:user,user:email
authorization - grant - type: authorization_code
redirect - uri: "{baseUrl}/login/oauth2/code/{registrationId}"
client - name: GitHub
- 配置资源服务器,保护受OAuth2保护的资源:
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/api/**").authenticated();
}
}
- 安全事件监听和审计
- 实现
ApplicationListener接口监听Spring Security相关事件,如登录成功、失败事件等。
- 实现
import org.springframework.context.ApplicationListener;
import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
import org.springframework.stereotype.Component;
@Component
public class LoginSuccessListener implements ApplicationListener<AuthenticationSuccessEvent> {
@Override
public void onApplicationEvent(AuthenticationSuccessEvent event) {
// 记录登录成功日志或进行其他审计操作
System.out.println("用户 " + event.getAuthentication().getName() + " 登录成功");
}
}
- 类似地,可以监听
AuthenticationFailureBadCredentialsEvent等事件来记录登录失败信息,实现审计功能。
更多推荐





所有评论(0)