提供配置弹簧安全性的方法?

是否可以以从外部文件读取配置详细信息并相应配置的方式配置Spring安全性。

(我不是在运行时更改配置。我正在谈论在启动时从文件中读取)

我现有的 Sporing安全配置示例如下:

@EnableWebSecurity @Configuration public class SecurityConfig { @Bean public UserDetailsService userDetailsService() throws Exception { InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager(); manager.createUser(User.withUsername("user").password("userPass").roles("USER").build()); manager.createUser(User.withUsername("admin").password("adminPass").roles("ADMIN").build()); return manager; } @Configuration @Order(1) public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter { @Override public void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication().withUser("user").password("user").roles("USER"); auth.inMemoryAuthentication().withUser("admin").password("admin").roles("ADMIN"); } protected void configure(HttpSecurity http) throws Exception { http .antMatcher("/api/v1/**") .authorizeRequests() .antMatchers("/api/v1/**").authenticated() .and() .httpBasic(); } } @Configuration @Order(2) public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { @Override public void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication().withUser("user1").password("user").roles("USER"); auth.inMemoryAuthentication().withUser("admin1").password("admin").roles("ADMIN"); } @Override protected void configure(HttpSecurity http) throws Exception { http .antMatcher("/api/test/**") .authorizeRequests() .antMatchers("/api/test/**").authenticated() .and() .formLogin(); } } } 

如您所见,我正在使用多个配置(查看Order()注释)。 我希望能够做的是在启动次数和配置类型时决定。 示例第一客户端可能希望具有2个配置,例如LdapConfigSamlConfig 。 其他人可能想要LdapConfigSqlConfig ,第三个可能需要4-5个配置。 有可能吗?

注意 :我没有使用Spring Boot

编辑

我为什么这样做的总结:

客户我指的是将购买我的产品的公司。 用户指的是购买我产品的公司的实际最终用户。 所以我把产品运到了3家公司。 首先将它配置为具有ldap auth flowgoogle-oauth2 auth流 。 第一家公司的用户将看到包含这两个选项的登录页面。 公司2现在可能有一个ldap auth流saml auth流程 ,该公司的用户将看到这两个选项。 该公司正在启动之前选择可用的选项。

在创建WebApplicationContext之前,您可以加载属性,例如DB凭据。 请看以下示例:

 public class WebAppInitializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext servletContext) throws ServletException { // Tell the EnvironmentManager to load the properties. The path to the config // file is set by Tomcat's home variable. If you change the container you might // need to change this, too. EnvironmentParamManager.initialize(System.getProperty("catalina.home")); // now create the Spring Context AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext(); rootContext.register(RootConfig.class); rootContext.setServletContext(servletContext); SpringApplicationContextProvider.configure(rootContext); // ... other config } 

EnvironmentParamManager可能如下所示。 我决定将它设置为静态,以便即使在应用程序的非Spring部分也可以从任何地方访问这些属性。

 public class EnvironmentParamManager { private static Properties properties = new Properties(); public static void initialize(String pathToConfigFile) { BufferedInputStream stream; try { stream = new BufferedInputStream(new FileInputStream( pathToConfigFile + "myconfig.props")); properties.load(stream); stream.close(); } catch (Throwable e) { throw new Error("Cannot read environment settings from file " + pathToConfigFile); } } public static String getMongoDBHostname() { return properties.getProperty("mongodb.username"); } } 

使用JavaConfig时,您可以像这样轻松地在Bean创建阶段访问配置属性

 @Configuration public class CoreConfig { @Bean public MongoDbFactory mongoDbFactory() throws Exception { ... ServerAddress address = new ServerAddress(EnvironmentParamManager.getMongoDBHost(), EnvironmentParamManager.getMongoDBPort()); ... } 

当然,您可以自由地连接到LDAP等任何其他服务,就像在引导Spring Context之前加载本地属性文件一样。 希望有所帮助。

使用Springs @Conditional注释@Conditional组件的选择性加载。

配置看起来像这样:

 @Configuration(value = "some.security.config") @Conditional(value = LoadSecurityConfigCondition.class) public class SomeSecurityConfig { // some code } @Configuration(value = "other.security.config") @Conditional(value = LoadSecurityConfigCondition.class) public class OtherSecurityConfig { // other code } 

然后, LoadSecurityConfigCondition.class决定是否加载了组件:

 @Component public class LoadSecurityConfigCondition implements Condition { @Override public boolean matches(final ConditionContext context, final AnnotatedTypeMetadata metadata) { boolean enabled = false; if (metadata.isAnnotated(Configuration.class.getName())) { final String name = (String) metadata.getAnnotationAttributes(Configuration.class.getName()).get("value"); if (StringUtils.isNotBlank(name)) { /* Here you may load your config file and * retrieve the information on wether to load * the config identified by its name. */ enabled = ...; } } return enabled; } } 

在此示例中,现在可以使用@Configuration名称创建配置条目,后缀为.enabled以阐明其用途:

 some.security.config.enabled=true other.security.config.enabled=false 

你试过这个:

 @EnableWebSecurity @Configuration public class SecurityConfig { @Bean public UserDetailsService userDetailsService() throws Exception { InMemoryUserDetailsManager manager = new MemoryUserDetailsManager(); manager.createUser(User.withUsername("user").password("userPass").roles("USER").build()); manager.createUser(User.withUsername("admin").password("adminPass").roles("ADMIN").build()); return manager; } @Configuration @Profile({"profile1", "profile2"}) @Order(1) public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter { @Override public void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication().withUser("user").password("user").roles("USER"); auth.inMemoryAuthentication().withUser("admin").password("admin").roles("ADMIN"); } protected void configure(HttpSecurity http) throws Exception { http .antMatcher("/api/v1/**") .authorizeRequests() .antMatchers("/api/v1/**").authenticated() .and() .httpBasic(); } } @Configuration @Profile("profile1") @Order(2) public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { @Override public void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication().withUser("user1").password("user").roles("USER"); auth.inMemoryAuthentication().withUser("admin1").password("admin").roles("ADMIN"); } @Override protected void configure(HttpSecurity http) throws Exception { http .antMatcher("/api/test/**") .authorizeRequests() .antMatchers("/api/test/**").authenticated() .and() .formLogin(); } } } 

因此,使用spring.profiles.active=profile1 ,加载两个配置,使用spring.profiles.active=profile2 ,仅加载第一个配置。 当然,您可以使用2个以上的配置文件,也可以在启动时激活多个配置文件(也以逗号分隔)。 您只需要以符合您要求的方式划分配置和配置文件。