Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

171
Views
Spring profile default behaviour

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());
}
over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

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.

over 4 years ago · Santiago Trujillo Report

0

I would override the bean definition in this way:

@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

}

In this way when the "DEV" profile is started the beans defined in that profile should override the default beans

Sure when you autowire beans you should use the @Qualifier annotation

I hope it's useful

Angelo

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!