0

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

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

@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 Security 版本是 3.2.9.RELEASE。

4

1 回答 1

1

由于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,您可以使用KeyStoreAPI 来完成。

当然,正如您所提到的,您不必使用KeyStore. 无论您将密钥存储在何处,都可以实现自己的密钥KeyManager并使用 OpenSAMLCollectionCredentialResolver代替KeyStoreCredentialResolver.

于 2021-03-18T15:29:31.703 回答