一、Spring Security 关键特性
1. 身份验证(Authentication):
- 支持多种身份验证方式,如用户名密码、LDAP、OAuth2、JWT 等。
- 提供用户详情服务(UserDetailsService)来加载用户特定数据。
2. 权限认证(Authorization):
- 基于角色和权限进行细粒度的访问控制。
- 使用方法级别和 URL 级别的安全性注解。
3. 防止常见攻击:
- 内置防御机制,如 CSRF(跨站请求伪造)、会话固定攻击等。
4. 灵活的配置:
- 提供基于 Java 配置和 XML 配置的多种方式。
- 支持自定义安全配置,如过滤器链、访问决策管理器等。
二、Spring Security 基本使用
1.引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
2.安全配置类:
创建一个配置类,继承 `WebSecurityConfigurerAdapter` 并重写相关方法:
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;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/public/").permitAll() // 允许所有人访问 /public 下的资源
.anyRequest().authenticated() // 其他请求需要身份验证
.and()
.formLogin() // 启用默认的登录页面
.permitAll()
.and()
.logout() // 启用默认的注销功能
.permitAll();
}
}
3.方法级别安全: 在应用中启用方法级别的安全控制:
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
@Service
public class MyService {
@PreAuthorize("hasRole('ADMIN')")
public void adminMethod() {
// 只有 ADMIN 角色的用户才能调用此方法
}
@PreAuthorize("hasAuthority('READ_PRIVILEGE')")
public void readMethod() {
// 只有具有 READ_PRIVILEGE 权限的用户才能调用此方法
}
}
4.用户和权限的配置: 使用内存中的用户存储进行简单的用户和权限配置:
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.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
@Configuration
public class UserConfig {
@Bean
@Override
public UserDetailsService userDetailsService() {
UserDetails user =
User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build();
UserDetails admin =
User.withDefaultPasswordEncoder()
.username("admin")
.password("password")
.roles("ADMIN")
.build();
return new InMemoryUserDetailsManager(user, admin);
}
}