MST

星途 面试题库

面试题:缓存设计之持久化缓存隐私保护策略

当多个用户共享持久化缓存时,如何设计隐私保护策略,防止用户间的数据泄露?请从身份验证、访问控制等方面详细阐述,并结合具体的后端开发框架(如Spring Boot)说明实现思路。
48.8万 热度难度
后端开发缓存设计

知识考点

AI 面试

面试题答案

一键面试

身份验证

  1. 用户认证方式
    • 用户名密码认证:用户在登录时提供用户名和密码,后端通过数据库验证其正确性。在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
  1. 认证持久化 使用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;
    }
}

访问控制

  1. 基于角色的访问控制(RBAC)
    • 定义角色:如ROLE_ADMINROLE_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";
    }
}
  1. 基于资源的访问控制(RBAC)
    • 为每个资源定义权限:如对特定缓存数据的读、写权限。在Spring Boot中,可以自定义AccessDecisionVoterSecurityMetadataSource实现细粒度的资源访问控制。例如:
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;
    }
}
  1. 数据隔离
    • 租户隔离:如果缓存数据按租户划分,每个用户属于一个租户。在缓存读取和写入时,通过当前用户所属租户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);
    }
}

加密

  1. 数据加密存储 在将数据存入持久化缓存前,使用加密算法对敏感数据进行加密。例如使用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;
        }
    }
}
  1. 传输加密 使用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