I want to create a library (let’s call it common-library) where I need to include classes from Spring Security.
How to include Spring Security as a dependency without triggering auto-configuration?
Idea is that Spring Security will be configured by different library (called secure-library - also includes Spring Security).
If only the common-library is included in an application then Spring security must not be enabled, but if both, common-library and secure-library, libraries are included that Spring Security is enabled and configured by secure-library.
Classes I actually need to include:
org.springframework.security.core.context.SecurityContextHolder;
org.springframework.security.oauth2.provider.OAuth2Authentication;
org.springframework.security.oauth2.provider.OAuth2Request;
BTW: I could not find jar with OAuth2Authentication,
OAuth2Request and without auto configuration.
Related
And most important, what's the reason behind the "Auto" prefix? Classes annotated with #Configuration rather than #AutoConfiguration are less automatic or something?
#Configuration is a spring framework annotation and not strictly bound to spring-boot. It was introduced when spring started to allow programmatic creation of spring-beans as to move forward from xml definitions of beans.
#AutoConfiguration is a spring-boot specific annotation not commonly available in spring framework. The reason it exists, is for external providers that cooperate with spring-boot to be able to mark some classes in some libraries they provide with this annotation as to inform spring-boot that those classes could be parsed and make some initializations during start up of spring application automatically.
So if some regular programmer that develops some application happens to have kafka in dependencies then some beans will automatically be created and added in application context and will be ready for the programmer to use, although he has not defined any configuration for them. Spring-boot already knows this as the kafka provider has already informed by marking some class in the jar they provide with the annotation #AutoConfiguration.
For this reason #AutoConfiguration has some more powerful configurations available as before, after, beforeName, afterName as to allow the provider to specify when the configuration is applied during application startup if some order is necessary.
So this annotation is not to be used from some regular programmer that develops an application using spring-boot. It is for someone that develops a library that other users might use with spring-boot. One such example is kafka library.
For this to work in a spring-boot project #EnableAutoConfiguration is needed as well, to enable auto configuration.
From spring documentation
Spring Boot auto-configuration attempts to automatically configure
your Spring application based on the jar dependencies that you have
added. For example, if HSQLDB is on your classpath, and you have not
manually configured any database connection beans, then Spring Boot
auto-configures an in-memory database.
#Configuration instead is to be used from some regular programmer that develops an application using spring-boot or spring-framework as to inform the framework for which beans should be created and how.
#AutoConfiguration was introduced in 2.7 with the idea to mark all auto-configurations with its dedicated annotation and move away from spring.factories for auto-configuration imports in 3.0 as described in Github issue.
According to Spring documentation:
[#AutoConfiguration] indicates that a class provides configuration that can be
automatically applied by Spring Boot. Auto-configuration classes are
regular #Configuration with the exception that
Configuration#proxyBeanMethods() proxyBeanMethods is always false.
Usually, #AutoConfiguration classes automatically configure an application based on the dependencies that are present on the classpath. Those classes are generally marked as #ConditionalOnClass and #ConditionalOnMissingBean annotations that detect the presence or absence of specific classes.
Additionally, if a configuration needs to be applied in a specific order, you can use the before, beforeName, after, and afterName attributes on the #AutoConfiguration, unlike #Configuration which doesn't provide those attributes.
I'm totally new to Kafka and terribly confused by this:
https://docs.spring.io/spring-kafka/reference/html/#with-java-configuration-no-spring-boot
I don't understand what that even means. What does "no spring boot mean" because that example sure as hell uses spring boot. I'm so confused....
EDIT
if I'm using SpringBoot and spring-kafka, should I have to manually create #Bean ConcurrentKafkaListenerContainerFactory as shown here. Most of the examples in the docs for setting up filtering / config / etc seem to use the "manual" configuration using #Bean. Is that "normal"? The docs are very confusing to me...especially this warning:
Spring for Apache Kafka is designed to be used in a Spring Application Context. For example, if you create the listener container yourself outside of a Spring context, not all functions will work unless you satisfy all of the …Aware interfaces that the container implements.
It's referring to the autowired configuration, as compared to putting each property in the config via HashMap/Properties in-code.
Also, it does not use #SpringBootApplication or SpringApplication.run, it just calls a regular main method using a hard-coded Config class.
Spring boot contains the functionality of AutoConfiguration
What this means is that spring boot when discovers some specific jar dependencies it knows, in the project, it automatically configures them to work on a basic level. This does not exist in simple Spring project where even if you add the dependency you have to also provide the configuration as to how it should work in your application.
This is also happening here with dependencies of Kafka. Therefore the documentation explains what more you have to configure if you don't have spring-boot with auto-configuration to make kafka work in a spring project.
Another question asked in comment is what happens in case you want some complex custom configuration instead of the automatic configuration provided while you are in a spring-boot app.
As documented
Auto-configuration tries to be as intelligent as possible and will
back-away as you define more of your own configuration. You can always
manually exclude() any configuration that you never want to apply (use
excludeName() if you don't have access to them). You can also exclude
them via the spring.autoconfigure.exclude property.
So if you want to have some complex configuration which is not automatically provided by spring-boot through some other mechanism like a spring-boot specific application property, then you can make your own configuration with your custom bean and then either automatic configuration from spring-boot for that class will back of as spring does several intelligent checks during application context set up or you will have to exclude the class from auto configuration manually.
In that case you could probably take as an example reference of how to register manually your complex configurations in spring boot what is documented on how to be done in non spring boot app. doc
Im trying to connect to Pivotal Cloud Cache server Regions.
I'm using #EnableClusterAware and trying to configure the client Regions via ClientRegionFactoryBean as below:
#Bean("clientRegion")
ClientRegionFactoryBean someClientRegion(GemFireCache gemfire) {
// ...
}
Either GemFireCache or ClientCache beans are not available with the annotation #EnableClusterAware. It's available only with #ClientCacheApplication.
Is there any annotations that needs to be used in conjunction with #EnableClusterAware so that GemFireCache gets injected?
Please help.
When Spring Boot for Apache Geode, or alternatively GemFire, (SBDG) is on the classpath of your Spring Boot application (see here), then SBDG auto-configuration will automatically create and configure a ClientCache instance for you (see here).
TIP: You can also review the Getting Stated Sample Guide and Source to see this behavior in action, for yourself. The Guide also talks about the use of the #EnableClusterAware annotation, here.
The #EnableClusterAware annotation is simply a development-time, SBDG annotation that enables you to switch between environments (e.g. local vs. managed, such as when pushing your Spring Boot application up to run in PCF, connected to PCC, and then testing locally in your IDE) without having to change any configuration (hence the goals).
The #EnableClusterAware annotation does not create any GemFire/Geode cache instances for you. Only SBDG's auto-configuration, or declaring an explicit SDG annotation (e.g. #ClientCacheApplication) will do that for you. Still, when using SBDG auto-configuration, you do not need an explicit SDG cache application annotation, like #ClientCacheApplication, since SBDG auto-configuration (again) creates and configures a ClientCache instance by default.
TIP: See the documentation on the #EnableClusterAware annotation for more details.
If ClientCache is not provided (auto-configured), then you are not:
Using SBDG, or rather do not have SBDG on the Spring Boot application classpath (see here)
Have not bootstrapped or configured and ran your Spring application with Spring Boot
Your Spring Boot application configuration is incorrect
You have explicitly disabled or overrode the SBDG auto-configuration
Etc.
One or more of these have to be true.
Well i'm building some personal project to learn spring roo 2. Now i'm struggling with spring security. There is little information about spring roo 2 in google and many relatively useful information on spring boot relating to spring roo.
with the command "security setup" you got the "--provider" option.
This is the description that the help gives you:
optional --provider: The Spring Security provider to install. Possible values are: DEFAULT (default Spring Security configuration provided by Spring Boot will be used), and SPRINGLETS_JPA (advanced Spring Security configuration will be included using Springlets JPA Authentication).; default: 'DEFAULT'
I couldn't find the difference between these two options, even on the spring roo M3 reference documentation. Even searching for "Springlets JPA Authentication" gives no information about it.
Anyone has any clue about this?
Thanks
These are the main differences between this two providers:
DEFAULT: Is the default Spring Security auto-configuration provided by Spring Boot when you include the spring-boot-starter-security in your project classpath. This is the default option because Spring Roo always tries to generate applications that use the auto-configuration provided by Spring Boot.
Selecting this provided the following changes will be applied to your project:
spring-boot-starter-security dependency will be included to your pom.xml file
If you want to know more information about this configuration you should check the spring boot reference guide
SPRINGLETS_JPA: If you select this provider, the default Spring Security auto-configuration provided by Spring Boot will be used. In addition, this provider will include the Springlets library to your classpath that provides you some extra starters to auto-configure advanced Spring Security properties. Also, configures the security authentication to use and user from the database instead of the default in-memory authentication provided by Spring Boot auto-configuration. You will be able to manage these configuration using the application.properties file and including the properties springlets.security.auth.in-memory.enabled and springlets.security.auth.in-memory.erase-credentials.
Selecting this provided the following changes will be applied to your project:
springlets-boot-starter-authentication dependency will be included to your pom.xml file
security.enable-csrf=true property will be included to enable CSRF. Know more about CSRF and Spring Security here
To know more about the Springlets Security project check the Springlets project page
Hope it helps,
tl/dr (How) Is it possible to use a jar library, that uses Spring Boot for configuration in a non Spring Boot (regular old-school Spring) server.
We have the problem, that we have a Spring server, that is from the pre-Boot times and we want to create a new library for it. We would like to use Spring Boot in the library (i.e. #EnableAutoConfiguration for configuration). To include the library we have put an spring.xml into the library that enables component-scan inside the library. The classes inside the library use #EnableAutoConfiguration and #EnableWebSecurity to enable configuration and security.
If we include now the library into our server and import the XML file from the library into the server's XML file, only parts of the configuration are working. The #RequestMappings in the library are working and the interfaces are available. However Spring security fails to register it's default filter chain, leading to ugly errors, where the regular Spring Boot config should already work with AnonymousAuthorizationFilter, etc.
We debugged, that the FilterRegistrationBean in spring security is never configured when running that way (and is, if we are running as a Spring Boot application).
So is there a common way how to deal with Spring Boot enabled libraries inside old-school Spring servers?
Is placing a single XML to enable component-scan in the library and importing this XML inside the main server's XML the correct way to include Spring Boot libraries (and how would be the best way, if the server would use Spring Boot itself)?
Does anyone know of the issue with a missing Spring Security filter chain?
PS: I know that we can add the required filters manually. However if we would do that, we would anyway get rid of Spring Boot completely in the library, so this question mainly aims for how to do it with Spring Boot. Of course if it is the wrong way to enable Spring Boot inside a library, please also mention that :-)