Spring Boot: purpose of #EnableSocial anotation - spring

in my Spring Boot app I am implementing the social login using Spring Social (1.1.4.RELEASE), I have following configuration class:
#Configuration
#EnableSocial
public class SocialConfig extends SocialConfigurerAdapter {
I see that #EnableSocial calls #Import(SocialConfiguration.class), but when I remove annotation #EnableSocial the social login works the same and SocialConfiguration is used anyway.

It's difficult to say without knowing more about your code, but even if you don't use #EnableSocial, Spring Boot will still assume you mean to use it if you provide sufficient social information (I'll use Facebook as an example here):
Your project depends on org.springframework.social:spring-social-facebook directly or transitively through for example org.springframework.boot:spring-boot-starter-social-facebook.
You specify information that the app can use to connect to the social network site. To figure out exactly what you need for Spring Boot to automatically configure it, you should check out the AutoConfiguration class for the social site in question, for example FacebookAutoConfiguration.
By the way, here's an example on how to get it working without #EnableSocial. Does it look similar to your setup? https://spring.io/guides/gs/accessing-facebook/

Related

How configure Spring Boot to show a custom #Endpoint in the base path '/actuator' but alphabetically?

In Spring Boot 2.4.1. For a custom #Endpoint I have the following:
#Component
#Endpoint(id="springhost")
class SpringHostEndpoint {
#ReadOperation()
HostInfo report() {
...
}
}
It works fine, the custom #Endpoint appears under the .../actuator base path how /springhost as follows:
From above it is the second link or item.
The situation is that it is not located in the right place such as all the rest of endpoints, it according alphabetically
How configure Spring Boot to accomplish that automatically?
Spring Boot does not sort the links returned by the /actuator endpoint. While in such cases it is preferable that sorting is done on the client side, I've raised an issue to see if this is something we want to consider doing in a future release.

Configuring spring-oauth2-client for non boot spring framework

In spring boot, application.yml takes in the Spring oauth2 client config. How do I configure it for the non-boot application. By configuration I mean giving client ID, secret, scopes and redirect URI.
You could find an example here:
https://www.baeldung.com/spring-security-5-oauth2-login#non-boot
You need to:
Build your ClientRegistration.
A ClientRegistrationRepository.
Register your repository on WebSecurityConfigurerAdapter.
If you don't use SpringBoot : there is no application.yml and even if you can add the support of yml files. It won't handle your oauth2 client config.
Anyway you can use Spring security to implement your custom Authorization Service, a User service and implement a Token Store of your choice (JBDCTokenStore or JWTTokenStore for example). But It's a very wide question depending on your business logic.
You can find some well documented samples on :
https://github.com/spring-projects/spring-security-oauth/tree/master/spring-security-oauth2
Of course you can handle both XML and javaConfig even mixed Spring confugurations.
Create a #Configuration class with a #ComponentScan on the packages containing components or bean definitions.
#Configuration
#ComponentScan({ "com.firm.product.config.xml","com.firm.product.config.java" })
public class SpringConfig {
}
You can also set properties with #PropertySource() ans #Value annotations. It's very well documented.

JerseyConfig and #Profile to hide a REST endpoint

I'm trying to hide a REST endpoint based on runtime configuration in Spring and Jersey. The most straightforward way is to throw the NotFoundException from the controller itself but maybe there's more kosher. The controller is registered in the constructor of the config class which extends org.glassfish.jersey.server.ResourceConfig.
I thought of using the #Profile annotation on the controller but I can still access the endpoint. When I hit that endpoint, I get the following error:
o.g.j.s.s.SpringComponentProvider - None or multiple beans found in Spring context
but then Jersey manages to access that controller, which I confirmed by attaching a debugger to the Spring process. So Jersey does not honor the #Profile setting.
On a separate note, I also have Swagger plugged into Jersey and when accessing the definition endpoint (.../swagger.json) I can see the endpoint provided by the #Profile-disabled controller.
Is there anything better I can do here is is throwing the NotFoundException the best option?
Note: Sorry, I thought I saw that you were using Spring Boot. The following answer is only relevant for Spring Boot.
#Profile is only good for Spring bean registration, but you are still registering the service with Jersey as a resource. What you can do is use a ResourceConfigCustomizer and add the #Profile to the customizer. This way it will only register the resource with Jersey ResourceConfig if the correct profile is active.
#Component
#Profile("..")
public class MyResourceConfigCustomizer implements ResourceConfigCustomizer {
#Override
public void customize(ResourceConfig config) {
config.register(MyResource.class);
}
}

Spring boot auto configuration with dependency and without #ComponentScan

Spring boot provides #ComponentScan to find packages to be scanned.
I am building a library which has #RestControllers inside with package com.mylib.controller. There are other classes as well with stereotype annotations in different packages.
So, if some one is developing SpringBoot Application with com.myapp base package.
He uses my library in his application. He need to mention #ComponentScan("com.mylib") to discover stereotype components of library.
Is there any way to scan components without including library package in #ComponentScan?
As spring-boot-starter-actuator expose its endpoints just with dependency, without defining #ComponentScan. OR any default package which is scanned regardless of application base package.
You could create a Spring Boot Starter in the same style as the Spring Provided Starters. They are essentially a jar'd library with a a spring.factories file pointing to the #Configuration class to load with some other annotations on there to provide overriding/bean back off (#ConditionalOnMissingBean) and generally provide their own #ConfigurationProperties.
Stéphane Nicoll provided an excellent demo of how to build one.
https://github.com/snicoll-demos/hello-service-auto-configuration
It is also documented in the Spring Boot documentation. https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-auto-configuration.html
The library approach would also work but I see no benefit in not making it a starter. Additionally for any library/starter I'd recommend dropping the #ComponentScan and just defining the beans in a #Configuration. This will work for sterotypes like #RestController etc. will function as normal if you create an #Bean out of it in a configuration.
Spring boot starter are special artifacts designed by Spring and used by Spring.
You can check that in the source code that contains mainly a
spring.provides file :
provides: spring-boot-actuator,micrometer-core
I don't know the exact way to process in the same way as Spring Boot Starter but as probably acceptable workaround, you could define in your jar a #Configuration class that specifies #ComponentScan("com.mylib").
#Configuration
#ComponentScan("com.mylib")
public class MyLibConfig {
//...
}
In this way, clients of the jar need "only" to import the #Configuration class :
#Import(MyLibConfig.class)
#Configuration
public class ClientConfig{
//...
}

Spring Security 4 & CDI

I want to use SpringSecurity4 in a CDI/EJB environment.
Is this possible? Can SpringSecurity can be used without using Spring?
What I want to do, is to use SpringSecurity with my EJB and CDI components.
Spring Security is basically a filter machine, filtering all the incoming requests. However, plenty of it's functionality is Spring-core dependent. It is possible to utilize Spring in a CDI application, but Spring's core is heavyweight and it's functionality is funny compared to CDI. That would be a downgrade and there would be no point in using CDI.
What you can do is to have a look at some Security projects for JEE world.
Apache DeltaSpike and it's Security module.
Keycloak - The absolute solution. Keycloak goes far, far beyond Spring security's functionality. It is an evolution of old PicketLink libraries developed by JBoss, but those are discontinued and merged into Keycloak instead. An example how simple usage of Keycloak is can be found here.
It is also not that hard to write own security interceptor using #WebFilter and #Inject :), there are several projects on GitHub:
https://github.com/rmpestano/security-interceptor
https://github.com/clairton/security
https://github.com/Rudin-Informatik/cdi-security
https://github.com/rafaelodon/my-security-context
I have no experience with these projects. However, I am always amazed how easily can Spring Security be replaced :)
I am using Spring Security with CDI but I can say it is not very healthy since Spring Security is based on spring and spring is messing with the CDI beans.
Here is what happened to me. I customized the AuthenticationProvider of spring security in order to authenticate users through my authentication server. When implementing this mechanism I used my predefined CDI beans by injecting them using (#Inject) annotation. At this point spring somehow intercepts the injection and creates its own bean, which means you cannot use any of the values you set to the CDI bean previously.
In order to solve this, I did some trick like this:
#Inject
private LoginController loginController;
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
//Here, the injected bean is empty, I am requesting my old bean from CDI and assign it back.
LoginController bm = (LoginController) CDI.current().select(LoginController.class).get();
loginController = bm;
I don't know if this is the answer you are looking for but i hope this helps...

Resources