2017-04-06 214 views
5

我有一个弹簧配置文件“DEV”,这是我唯一的配置文件,我不想创建“生产”配置文件。所以只有当配置文件是“DEV”时,我想为弹簧安全启动一个特定类型的bean(这是一个内存访客用户和一个userdetails bean)弹簧配置文件默认行为

但是,如果在我的tomcat启动时没有提供弹簧配置文件,这是生产中的情况,我希望我的应用程序继续它已经在做的事情(使用ldap authenticatin提供程序)。

有没有一种方法来定义一个“默认”的bean行为,而不需要在启动时提供配置文件?或者你可以看看我的代码,并建议一个不同的解决方案。

@Autowired 
public void configureGlobal(final AuthenticationManagerBuilder auth, final AuthenticationProvider provider) throws Exception { 

     auth 
       .eraseCredentials(false) 
       .authenticationProvider(provider) 
       .authenticationProvider(jwtConfig.jwtAuthenticationProvider()); 
} 


@Bean 
public UserDetailsService userDetailsService() { 
    final LdapUserDetailsService ldapUserDetailsService = new LdapUserDetailsService(ldapUserSearch(), ldapAuthoritiesPopulator()); 
    return new CompositeUserDetailsService(Arrays.asList(technicalUserDetailsService(), ldapUserDetailsService)); 
} 

@Bean 
@Profile("DEV") 
public UserDetailsService devUserDetailsService() { 
useAnonymous = true; 
     InMemoryUserDetailsManagerBuilder b = new InMemoryUserDetailsManagerBuilder() 
       .withUser("user").password("password").authorities(ROLE_USER, ROLE_ADMIN).and(); 

     return new CompositeUserDetailsService(Arrays.asList(b.build(), 
       technicalUserDetailsService())); 

} 
@Bean 
public AuthenticationProvider ldapAuthenticationProvider() { 
    final BindAuthenticator ba = new BindAuthenticator((BaseLdapPathContextSource) contextSource()); 
    ba.setUserSearch(ldapUserSearch()); 
    return new LdapAuthenticationProvider(ba, ldapAuthoritiesPopulator()); 
} 
+0

你已经试过了吗?如果是这样,是否出现了问题? – john16384

+0

通过定义bean并在配置文件处于活动状态时覆盖它...W这基本上是默认行为。 –

回答

6

我认为@Profile有什么误解。标记为@Profile的豆仅在该配置文件处于活动状态时加载,但所有其他豆(不带@Profile)仍然始终加载,而与所选配置文件无关。

我看到了几个方法来解决这个问题:

1)号码以@Profile("dev")@Primary所以Spring知道当两个相同类型的bean被装载哪一个选择(因为你DONOT希望所有这些bean使用生产配置文件)。

2)标志应该被当轮廓开发与@Profile("!dev")活跃装豆 - 仅适用于春季3.2和更高版本(见https://github.com/spring-projects/spring-framework/commit/bcd44f3798ed06c0704d2a3564b8a9735e747e87)。

或者......

3)使用生产概况,并简单地激活它在例如web.xml文件(一些东西,你可能不能在本地使用)。

只需创建多个@Configuration类,并用一个配置文件标记整个班级(这也有助于将相关内容保存在一起)。一个典型的例子是数据库。为生产数据库创建一个配置类(使用JNDI和Oracle),另一个用于本地开发和测试(HSQLDB)。

您使用@Profile("production")标记JNDI配置类,另一个使用@Profile("dev") - 无需标记单个bean,只需在两个不同的@Configuration类之间进行逻辑分割即可。

这对我们来说非常合适,并且与集成测试结合在一起。

+0

tnx,你的第一个解决方案似乎对拾取正确的豆子很好,但不知何故,我仍然无法与我的访客用户登录。有没有办法使用“auth.userDetailsS​​ervice(userDetailsS​​ervice())”当它是开发人员配置文件和“auth.authenticationProvider(供应商)”时,不开发?这在我的示例中的第一种方法中配置了 – Spring

+0

回答这个问题看起来有点不完整......但是,我认为你应该制作两个'AuthenticationManager' bean,一个具有'dev'配置文件,另一个没有(或者带有! dev')。在这两种方法中,您可以根据配置文件以不同的方式构建bean。 – john16384

+0

谢谢。顺便说一句主注释不适用于我,我使用了“!DEV”语法 – Spring

1

我会重写bean定义这样:

@Autowired 
public void configureGlobal(final AuthenticationManagerBuilder auth, final AuthenticationProvider provider) throws Exception { 

     auth 
       .eraseCredentials(false) 
       .authenticationProvider(provider) 
       .authenticationProvider(jwtConfig.jwtAuthenticationProvider()); 
} 


@Bean("myUserDetailService") 
public UserDetailsService userDetailsService() { 
    final LdapUserDetailsService ldapUserDetailsService = new LdapUserDetailsService(ldapUserSearch(), ldapAuthoritiesPopulator()); 
    return new CompositeUserDetailsService(Arrays.asList(technicalUserDetailsService(), ldapUserDetailsService)); 
} 

@Bean("myUserDetailService") 
@Profile("DEV") 
public UserDetailsService devUserDetailsService() { 
useAnonymous = true; 
     InMemoryUserDetailsManagerBuilder b = new InMemoryUserDetailsManagerBuilder() 
       .withUser("guest").password("guest").authorities(ROLE_USER, ROLE_ADMIN).and(); 

     return new CompositeUserDetailsService(Arrays.asList(b.build(), 
       technicalUserDetailsService())); 

} 
@Bean("myAuthProvider") 
public AuthenticationProvider ldapAuthenticationProvider() { 
    final BindAuthenticator ba = new BindAuthenticator((BaseLdapPathContextSource) contextSource()); 
    ba.setUserSearch(ldapUserSearch()); 
    return new LdapAuthenticationProvider(ba, ldapAuthoritiesPopulator()); 
} 

@Bean("myAuthProvider") 
@Profile("DEV") 
public AuthenticationProvider devAuthenticationProvider() { 

    //find a way to return userdetails here 

} 

这样当“DEV”轮廓开始在配置文件定义的豆应覆盖默认豆

当你自动安装豆时,你应该使用@Qualifier注释

我希望它有用

Angelo