Tengo un perfil de primavera "DEV" y ese es el único perfil que tengo y NO quiero crear un perfil de "producción". Entonces, solo cuando el perfil es "DEV", me gustaría que se inicie un cierto tipo de bean para la seguridad de primavera (que es un usuario invitado en la memoria y un bean de detalles del usuario)
Pero si no se proporciona un perfil de resorte en mi inicio de Tomcat, que es el caso en producción, me gustaría que mi aplicación continúe con lo que ya está haciendo (utilizando el proveedor de autenticación ldap).
¿Hay alguna manera de definir un comportamiento de bean "predeterminado" sin tener que proporcionar un perfil al inicio? O puede mirar mi código a continuación y sugerir una solución diferente tal vez.
@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()); }Creo que hay un malentendido de lo que hace @Profile . Los beans marcados con @Profile solo se cargan cuando ese perfil está activo, pero todos los demás beans (sin @Profile ) siempre se cargan, independientemente del perfil elegido.
Veo algunas maneras de resolver esto:
1) Marque todos esos beans con @Profile("dev") también con @Primary para que Spring sepa cuál elegir cuando se cargan dos beans del mismo tipo (ya que no desea utilizar un perfil de producción).
2) Marque los beans que no deben cargarse cuando el perfil dev está activo con @Profile("!dev") -- solo aplicable para Spring 3.2 y versiones posteriores (consulte https://github.com/spring-projects/spring-framework /commit/bcd44f3798ed06c0704d2a3564b8a9735e747e87 ).
O...
3) Use un perfil de producción y simplemente actívelo, por ejemplo, en el archivo web.xml (algo que probablemente no use localmente).
Simplemente cree varias clases de @Configuration y marque toda la clase con un perfil (también ayuda a mantener juntas las cosas relacionadas). Un ejemplo típico es para la base de datos. Cree una clase de configuración para la base de datos de producción (algo con JNDI y Oracle) y otra para desarrollo y pruebas locales (HSQLDB).
Marca la clase de configuración JNDI con @Profile("production") y la otra con @Profile("dev") ; no es necesario marcar beans individuales, simplemente @Configuration lógicamente entre dos clases de @Configuración diferentes.
Esto funcionó muy bien para nosotros, también cuando se combinó con pruebas de integración.
Anularía la definición de bean de esta manera:
@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 }De esta forma, cuando se inicia el perfil "DEV", los beans definidos en ese perfil deben anular los beans predeterminados.
Claro, cuando autoconectas beans, debes usar la anotación @Qualifier
espero que sea util
Ángel