身份验证
- 用户认证方式
- 用户名密码认证:用户在登录时提供用户名和密码,后端通过数据库验证其正确性。在Spring Boot中,可以使用Spring Security框架,配置
UserDetailsService
接口实现用户信息的加载和密码验证。例如:
@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("User not found");
}
List<GrantedAuthority> authorities = Arrays.asList(new SimpleGrantedAuthority("ROLE_USER"));
return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), authorities);
}
}
- **OAuth2认证**:适用于第三方登录场景,用户通过授权第三方应用获取访问令牌。Spring Boot支持OAuth2集成,可配置客户端和资源服务器。如:
spring:
security:
oauth2:
client:
registration:
github:
client-id: your-client-id
client-secret: your-client-secret
scope: read:user,user:email
provider:
github:
authorization-uri: https://github.com/login/oauth/authorize
token-uri: https://github.com/login/oauth/access_token
user-info-uri: https://api.github.com/user
- 认证持久化
使用
Remember - Me
功能,Spring Boot通过在客户端存储加密的认证信息,在用户下次访问时自动认证。配置如下:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.rememberMe()
.key("unique-and-secret")
.tokenRepository(persistentTokenRepository())
.tokenValiditySeconds(1209600);
}
@Bean
public PersistentTokenRepository persistentTokenRepository() {
JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
tokenRepository.setDataSource(dataSource);
return tokenRepository;
}
}
访问控制
- 基于角色的访问控制(RBAC)
- 定义角色:如
ROLE_ADMIN
、ROLE_USER
等。在Spring Boot中,通过在UserDetails
中设置角色信息,并在Controller方法上使用@PreAuthorize
注解控制访问。例如:
@RestController
@RequestMapping("/api")
public class DataController {
@GetMapping("/admin/data")
@PreAuthorize("hasRole('ROLE_ADMIN')")
public String adminData() {
return "This is admin - only data";
}
@GetMapping("/user/data")
@PreAuthorize("hasRole('ROLE_USER')")
public String userData() {
return "This is user - accessible data";
}
}
- 基于资源的访问控制(RBAC)
- 为每个资源定义权限:如对特定缓存数据的读、写权限。在Spring Boot中,可以自定义
AccessDecisionVoter
和SecurityMetadataSource
实现细粒度的资源访问控制。例如:
public class CustomAccessDecisionVoter implements AccessDecisionVoter<Object> {
@Override
public boolean supports(ConfigAttribute attribute) {
return true;
}
@Override
public boolean supports(Class<?> clazz) {
return true;
}
@Override
public int vote(Authentication authentication, Object object, Collection<ConfigAttribute> attributes) {
// 根据资源和用户权限进行投票决策
return ACCESS_GRANTED;
}
}
- 数据隔离
- 租户隔离:如果缓存数据按租户划分,每个用户属于一个租户。在缓存读取和写入时,通过当前用户所属租户ID作为前缀或分区依据。在Spring Boot中,可以在缓存操作方法中添加租户ID参数,并在缓存配置中设置相应的缓存键生成策略。例如:
@Service
public class TenantDataService {
@Autowired
private CacheManager cacheManager;
public void saveTenantData(String tenantId, String key, Object value) {
Cache cache = cacheManager.getCache("tenant - cache");
cache.put(tenantId + ":" + key, value);
}
public Object getTenantData(String tenantId, String key) {
Cache cache = cacheManager.getCache("tenant - cache");
return cache.get(tenantId + ":" + key);
}
}
加密
- 数据加密存储
在将数据存入持久化缓存前,使用加密算法对敏感数据进行加密。例如使用AES算法,在Spring Boot中可以通过引入相关加密库(如Bouncy Castle)实现。
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.security.Security;
public class DataEncryptionUtil {
private static final String ALGORITHM = "AES";
private static SecretKey secretKey;
static {
Security.addProvider(new BouncyCastleProvider());
try {
KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM);
keyGenerator.init(256);
secretKey = keyGenerator.generateKey();
} catch (Exception e) {
e.printStackTrace();
}
}
public static String encrypt(String data) {
try {
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encryptedBytes = cipher.doFinal(data.getBytes());
return Base64.getEncoder().encodeToString(encryptedBytes);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static String decrypt(String encryptedData) {
try {
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] decodedBytes = Base64.getDecoder().decode(encryptedData);
byte[] decryptedBytes = cipher.doFinal(decodedBytes);
return new String(decryptedBytes);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
- 传输加密
使用HTTPS协议保证数据在网络传输过程中的安全。在Spring Boot中,可以通过配置SSL证书实现。例如在
application.properties
中配置:
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-password=password
server.ssl.keyStoreType=PKCS12
server.ssl.keyAlias=tomcat