我正在为我的公司设置 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/