I have a spring profile "DEV" and thats the only profile I have and I do NOT want to create a "production" profile. So only when profile is "DEV" I would like a certain type of bean for spring security is initiated (which is an in memory guest user and a userdetails bean)
But if no spring profile is provided in my tomcat startup, which is the case in production, I would like my app to continue what it is already doing(using ldap authenticatin provider).
Is there a way to define a "default" bean behaviour without actually needing to provide a profile at start up? Or you can look at my code below and suggest a different solution maybe.
@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());
}
The default profile is always active. Spring Boot loads all properties in application. yml into the default profile. We could rename the configuration file to application-default.
Spring Boot will automatically load the properties in an application. properties file for all profiles, and the ones in profile-specific . properties files only for the specified profile. In this way, we can easily provide different configurations for different environments.
By default, Spring Boot uses the 8080 port number to start the Tomcat. Let us learn how change the port number by using command line properties. Step 1 − After creating an executable JAR file, run it by using the command java –jar <JARFILE>.
A single @SpringBootApplication annotation can be used to enable those three features, that is: @EnableAutoConfiguration : enable Spring Boot's auto-configuration mechanism. @ComponentScan : enable @Component scan on the package where the application is located (see the best practices)
I think there is a misunderstanding of what @Profile
does. Beans marked with @Profile
are only loaded when that profile is active, but all other beans (without a @Profile
) are still always loaded, regardless of the chosen profile.
I see a few ways to solve this:
1) Mark all those beans with a @Profile("dev")
also with @Primary
so Spring knows which one to pick when two beans of the same type are loaded (since you donot want to use a production profile).
2) Mark the beans that should not be loaded when profile dev is active with @Profile("!dev")
-- only applicable for Spring 3.2 and higher (see https://github.com/spring-projects/spring-framework/commit/bcd44f3798ed06c0704d2a3564b8a9735e747e87).
Or...
3) Use a production profile and simply activate it in for example the web.xml
file (something which you probably don't use locally).
Simply create multiple @Configuration
classes and mark the entire class with a profile (it also helps to keep related stuff together). A typical example is for the database. Create one configuration class for the production database (something with JNDI and Oracle) and one for local development and testing (HSQLDB).
You mark the JNDI Configuration class with @Profile("production")
and the other with @Profile("dev")
-- no need to mark individual beans, just split them logically amongst two different @Configuration
classes.
This worked really well for us, also when combined with integration testing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With