Spring 安全 SAML2 核心 - 为在运行时创建的身份提供者添加密钥

Spring Secuirty SAML2 Core - Add a key for an Identity Provider created on runtime

目前,我正在使用 Spring 安全性编辑我项目中 SAML 支持的现有实现。 我有多个 IdentityProvider,我将它们的数据存储在数据库中。 使用我的应用 UI 我可以在运行时添加新的 IdentityProvider,这将被添加到 CachingMetadataManager。之后,调用 refreshMetadata。 但是我有 JKSKeyManager,它在应用程序启动时加载并加载一个 JKS 密钥库,该密钥库用于所有 IdentityProvider 的所有元数据。 我希望用户能够在运行时创建 IdentityProvider 期间使用我的应用程序 UI 上传(或粘贴)私钥,这样,不同的密钥可以用于不同的 IdentityProvider,但我不知道如何。如果我将密钥存储在 JKS 文件或其他地方,对我来说没有区别。 没有 spring 引导,恐怕无法将库 versions/migrate 升级到其他库。

密钥管理器注入如下所示:

@Bean
  public KeyManager keyManager() {
    DefaultResourceLoader loader = new DefaultResourceLoader();
    Resource storeFile = loader
        .getResource(environment.getProperty("server.ssl.key-store"));
    Map<String, String> passwords = new HashMap<>();
    passwords.put(environment.getProperty("server.ssl.key-alias"), environment.getProperty("server.ssl.key-store-password"));
    String defaultKey = "spring";
    return new JKSKeyManager(storeFile, environment.getProperty("server.ssl.key-store-password"), passwords, defaultKey);
  }

使用的 SAML 扩展名是来自 org.springframework.security.extensions 的 spring-security-saml2-core (1.0.3.RELEASE)。 Spring 安全版本是 3.2.9.RELEASE.

由于 JKSKeyManager 在构造时计算所有可用键,因此 KeyManager 的自定义实现可能是最好的。

类似于以下内容,例如:

public DynamicJKSKeyManager extends JKSKeyManager {
    private final KeyStore keyStore;

    public KeyStoreKeyManager(KeyStore keyStore, Map<String, String> passwords, String defaultKey) {
        super(keyStore, passwords, defaultKey);
        this.keyStore = keyStore;
    }

    @Override
    public Set<String> getAvailableCredentials() {
        try {
            Set<String> availableKeys = new HashSet<String>();
            Enumeration<String> aliases = keyStore.aliases();
            while (aliases.hasMoreElements()) {
                availableKeys.add(aliases.nextElement());
            }
            return availableKeys;
        } catch (KeyStoreException e) {
            throw new RuntimeException("Unable to load aliases from keyStore", e);
        }
    }
}

将更改 getAvailableCredentials 方法以在每次调用时读取 KeyStore 别名。

然后,当你需要在KeyStore中添加一个键时,你可以使用KeyStore API来完成。

当然,正如您所说,您不必使用KeyStore。无论您将密钥存储在何处,都可以实现自己的 KeyManager 并使用 OpenSAML 的 CollectionCredentialResolver 而不是 KeyStoreCredentialResolver.