spring-boot - 如何将 Spring Bean Autowiring 到 Lamba 代码中?

标签 spring-boot spring-security autowired

我正在为我的公司设置 spring-security saml 2.0 蓝图。

我正在关注 Ulises Bocchio 的 Howtos 。到目前为止一切都很好 - 示例身份验证过程运行良好。

为了遵循我们公司的安全准则,我必须使 SAMLConfig.java 文件可配置。我的第一个想法是 Autowiring 一个从“某处”加载配置的组件;像下面这样。

/**
* @author Ulises Bocchio
*/
@AutoConfigureBefore(WebSecurityConfig.class)
@Configuration
public class SAMLConfig {
  protected Logger log = LoggerFactory.getLogger(this.getClass());

  @Autowired
  private SAMLUserDetailsServiceImpl samlUserDetailsServiceImpl;


  @Autowired
  private SAMLProperties samlProperties;

  @Bean
  public SAMLAuthenticationProvider samlAuthenticationProvider() {
    final SAMLAuthenticationProvider provider = new SAMLAuthenticationProvider();
    provider.setUserDetails(this.samlUserDetailsServiceImpl);
    provider.setForcePrincipalAsString(false);
    return provider;
  }

这不起作用,因为 SAMLProperties 对象为 null。我不确定,但 Spring Security 有可能在其他(应用程序)组件之前启动吗?

如何实现Ulises Bocchio's的动态配置SAMLConfig.java 文件?

最佳答案

一位同事向我暗示了以下信息日志行:

@Bean method SAMLConfig.idpMetadataLoader is non-static and returns an object assignable to Spring's BeanFactoryPostProcessor interface. This will result in a failure to process annotations such as @Autowired, @Resource and @PostConstruct within the method's declaring @Configuration class. Add the 'static' modifier to this method to avoid these container lifecycle issues; see @Bean javadoc for complete details.

我对 Ulises Bocchio 的 idpMetadataLoader 方法的改编版本:

@Bean
BeanFactoryPostProcessor idpMetadataLoader(StaticBasicParserPool parserPool) {
return beanFactory -> {
  try {
    final Resource idpResource = new UrlResource(this.samlProperties.getIdpMetadataUrl());
    final String alias = this.samlProperties.getKeystoreAlias();
    final Timer refreshTimer = new Timer(true);

    final ResourceBackedMetadataProvider delegate =
        new ResourceBackedMetadataProvider(refreshTimer, new SpringResourceWrapperOpenSAMLResource(idpResource));
    delegate.setParserPool(parserPool);
    final ExtendedMetadata extendedMetadata = this.extendedMetadata().clone();
    final ExtendedMetadataDelegate provider = new ExtendedMetadataDelegate(delegate, extendedMetadata);
    provider.setMetadataTrustCheck(true);
    provider.setMetadataRequireSignature(false);
    extendedMetadata.setAlias(alias);
    beanFactory.registerSingleton(alias, provider);
  } catch (final Exception e) {
    this.log.error("Error while confiure SAML", e);
    e.printStackTrace();
  }
 };

}

重点是,lambda 代码被翻译为静态代码 - 因此无法访问非静态类成员。非常简单的解决方案是将配置作为方法参数传递。

  @Bean
  BeanFactoryPostProcessor idpMetadataLoader(SAMLConfigFile properties, StaticBasicParserPool parserPool) {
    return beanFactory -> {
  ...
  };
}

关于spring-boot - 如何将 Spring Bean Autowiring 到 Lamba 代码中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64787597/

相关文章:

spring-mvc - spring 安全与某些东西的冲突(也许是 spring mvc)

java - Spring Boot @CachePut 值为 null

java - 如何使用 Spring Boot 发布 oneToMany 关系数据库条目

spring - Thymeleaf:来自 messageKey 的默认消息

java - 使用 spring-security-oauth2 的 SSO : Authentication Code never read

tomcat - Spring Security、远程用户和 Tomcat 日志

java - Spring 无法在 Controller 中 Autowiring 存储库

spring - 为什么@Async 注释会导致循环引用问题?

java - 有没有办法访问 Springframework 存储库 "refresh"?

Spring:无法从父上下文 Autowiring bean