How does AuthenticationManager implementation gets instantiated in SpringBoot App - spring-boot

Including spring security starter dependency makes AuthenticationManager available in a spring boot application. I can simply Autowire the AuthenticationManager. How does SpringBoot understand to automatically instantiate the bean for AuthenticationManager though it is in a very different jar file ?
for e.g.
I can simply write
#Autowire
AuthenticationManager authManager;
in my SpringBoot App after including the dependency. How does spring know that it is supposed to instantiate which class and how ?

The class org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration imports the configuration class org.springframework.boot.autoconfigure.security.AuthenticationManagerConfiguration, which then provides the bean for the AuthenticationManager (it will use a builder to build the authentication manager according to the configuration which is provided).

Related

Flyway 6 JavaMigrations with Native Dependency Injection for Spring Beans

I have seen many great workarounds to create Flyway JavaMigrations and injecting Spring Beans using #DependsOn and ApplicationContextAware (e.g. https://stackoverflow.com/a/48242865/5244937).
However a part of the Flyway 6 documentation claims Dependency Injection would be possible natively for Spring Beans:
https://flywaydb.org/documentation/api/hooks#java-based-migrations-as-spring-beans
https://github.com/flyway/flyway/issues/1062
Is is true? How would this work?
Mark your migrations as #Component and put them in a folder that is scanned by spring (e.g. within your application package and not in db.migrations). This will ensure #Autowired can be used because the bean is instantiated by spring. (The migrations in db.migrations will be scanned by flyway automatically and are not instantiated by spring.)
Then implement a FlywayConfigurationCustomizer to add the migrations by loading them from the spring context:
#Configuration
class FlywayConfiguration implements FlywayConfigurationCustomizer {
#Autowired
private ApplicationContext applicationContext;
#Override
public void customize(FluentConfiguration configuration) {
JavaMigration[] migrationBeans = applicationContext
.getBeansOfType(JavaMigration.class)
.values().toArray(new JavaMigration[0]);
configuration.javaMigrations(migrationBeans);
}
}

Spring #configure annotation usage without bean definitions

I have some experience with spring dependency injection and transaction management but I am new to spring security. When i was reading an article related to spring security, I found that #Configuration annotation is used in an example but there were no bean definitions to be found.
According to my understanding, #Configuration annotation is used in classes which contain bean definitions. I need to know that what does the #Configuration annotation do in this example.
#Configuration
public class ApplicationSecurity extends WebSecurityConfigurerAdapter {
#Autowired
DataSource dataSource;
... // web stuff here
#Override
public configure(AuthenticationManagerBuilder builder) {
builder.jdbcAuthentication().dataSource(dataSource).withUser("dave")
.password("secret").roles("USER");
}
}
Thank you
It's not mandatory to have Bean definitions in Spring managed classes.
In this case #Configuration (which wraps #Component) is used to indicate to Spring that this class should be instantiated and all it's dependencies should be injected - in this case that's DataSource and AuthenticationManagerBuilder. This is an example of Inversion of Control principle.
Spring also provides these ConfigurerAdapter hook points, where you can tweak the default configuration of an already instantiated component.
This is exactly what is happening in your Configuration class.

Spring boot jersey - prevent startup instantiation of controller

I am using spring boot with web and jersey (spring-boot-jersey-starter). I have a Jersey endpoint that needs to inject a request scope bean. However, at startup of the application I am getting a no bean found error.
#Component
#Path("blah")
#RequestScoped
public class JerseyController{
#Inject
private MyEntity entity;
}
#Component
public class JerseyConfiguration extends ResourceConfig{
public JeyseyConfiguration(){
register(JeyseyController.class);
registere(MyEntityProvider.class);
}
}
Is there a way, in a spring-boot web app, to prevent Spring from attempting to instantiate and inject my JerseyController until an HTTP request is received so that the injected dependency can be provided by my Jersey provider?
#Component is not required on Jersey resources. Having it will cause Spring to instantiate it (with default Singleton scope). I don't think Spring doesn't respect the #RequestScoped. This is a Jersey annotation. If you want to use the #Component, I think the Spring #Scope("request") might do the trick though.
You can also remove the #RequestScoped. This is the default scope for Jersey resources.
The only time I have ever found a need to use #Component on Jersey resources, is if I need to use the Spring #Value (maybe AOP also, but I don't do much AOP). Other than that, the Jersey-Spring integration already supports the most common used feature of Spring which is DI. And if you really want to make the Jersey resource a singleton, Jersey supports the #Singleton annotation.

How to get Spring Boot to create a bean validator before creating all the other beans

I'm trying to add a LocalValidatorFactoryBean to an existing Spring Boot web application.
No matter what I have tried (listed in a moment) it only creates the validator after most other beans (verified with both logging and breakpoints), so they never get validated.
Tangentially, I have hibernate-validator on the classpath and am attempting to use javax.validation.constraints on my #Component properties.
Application class has #Configuration, #EnableAutoConfiguration and #ComponentScan({"my.package.**"}).
Adding an application.xml with the bean <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
Adding the above bean to validator.xml and adding #ImportResource("validator.xml")
Adding a new #Bean to the Application class. public Validator validator() { return new LocalValidatorFactoryBean(); }
Adding #Order(Ordered.HIGHEST_PRECEDENCE) to the above #Bean
Adding a BeanValidator #Component to the scanned packages.
And adding #Order to it.
In all cases, the validator is loaded only after FilterRegistrationBean has finished logging its business, but the beans I want to validate have already been created and used in setting up data connections and security for example.
Its been a few years since I've used Spring, but I don't remember these problems when defining everything in an application.xml. Is this just something that spring-boot doesn't support and I should move back to traditional Spring application config?
How can I get it to validate all my beans?
I forgot to make a BeanValidationPostProcessor.

AspectJ Advice on Spring Security ProviderManager throws exception on startup

Does anyone know why when I try to create an advice around the "doAuthentication" method of the Spring Security (v3.0) ProviderManager my application throws an exception on startup?
I am autowiring an instance of my spring authentication-manager bean into a controller and when the autowire is attempted my app fails to deploy.
Here is what my security context xml looks like...
...<authentication-manager alias="authenticationManager"> ...
Here is the pertinent part of my controller...
#Autowired
private ProviderManager authenticationManager;
and here is my advice declaration:
#After("execution(* org.springframework.security.authentication.ProviderManager.doAuthentication(..)) && args(authentication)")
Any help will be greatly appreciated!
I'm not sure from the available information, but I'm guessing that you're using Spring AOP, which uses JDK dynamic proxies by default, so you are coming across the usual problem that the proxy does not retain the type of the original class (ProviderManager). The proxy will implement the interface AuthenticationManager, however. Try autowiring using this type and see if it works. Either that or you can enable class proxying which uses cglib instead of dynamic proxies. If you're using the Spring AOP namespace, you can set the proxy-target-class attribute to true.

Resources