Spring Boot with Spring Social Google provider - spring-boot

Any example how to integrate Spring Boot application with Spring Social Google (GabiAxel/spring-social-google) provider? I found this project, but it seems to be unfinished. Spring Boot explains how to get it working with Spring Facebook, Twitter, but is it the same for log in with Google?

As you have mentioned in your question, you can use that project hosted on github.
You can use this dependency
In a Configuration class, you will have to extend SocialConfigurerAdapter, override the addConnectionFactories method and add GoogleConnectionFactory. For example :
#Configuration
#EnableSocial
public class SocialConfig extends SocialConfigurerAdapter {
#Override
public void addConnectionFactories(ConnectionFactoryConfigurer connectionFactoryConfigurer, Environment environment) {
GoogleConnectionFactory googleConnectionFactory = new GoogleConnectionFactory(environment.getProperty("spring.social.google.app-id"), environment.getProperty("spring.social.google.app-secret"));
googleConnectionFactory.setScope("https://www.googleapis.com/auth/plus.login");
connectionFactoryConfigurer.addConnectionFactory(googleConnectionFactory);
}
#Bean
#Scope(value = "request", proxyMode = ScopedProxyMode.INTERFACES)
public Google google(ConnectionRepository repository) {
Connection<Google> connection = repository.findPrimaryConnection(Google.class);
return connection != null ? connection.getApi() : null;
}
}
You can use this along with the Spring Social examples.

Related

How do you configure a self signed certificate programmatically with Spring Boot 3 for Tomcat?

Previous examples of how to configure a self signed certificate with Spring Boot 2.x looked something like this
#Component
public class MyTomcatWebServerFactoryCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
#Override
public void customize(TomcatServletWebServerFactory server) {
server.addConnectorCustomizers(connector -> {
Http11NioProtocol proto = (Http11NioProtocol) connector.getProtocolHandler();
proto.setSSLEnabled(true);
proto.setKeystoreFile(CERTIFICATE_PATH);
proto.setKeystorePass(CERTIFICATE_PASSWORD);
proto.setKeystoreType(KEYSTORE_TYPE);
proto.setKeyAlias(CERTIFICATE_ALIAS);
});
}
}
Spring Boot 3 moves to Tomcat 10 which removes setKeystoreFile, setKeystorePass, setKeystoreType, and setKeyAlias from the base classes for Http11NioProtocol and I am struggling to find the appropriate way to configure these same parameters in the new environment. I have done my due diligence searching the web but I am struggling to find the replacement method for doing this.

Application failed to start after spring boot version upgrade from 2.1.18.RELEASE to 2.2.0.RELEASE

When we upgrade the spring-boot-starter-parent version from 2.1.8.RELEASE to 2.2.0.RELEASE, the application is not loading few beans. Due to this, application is failing. #PostConstuct is not able to add BCFIPS Provider in security provider.
#Configuration
#Slf4j
#ComponentScan(basePackages = "com.xxx.yyy.ekms.sdk")
#ConditionalOnProperty(name = "ekms.enabled", havingValue = "true")
public class EKMSClientSdkConfiguration extends ClientConfiguration
{
#PostConstruct
public void addSecurityProvider()
{
Security.addProvider(new BouncyCastleFipsProvider());
}
#Bean
public ApiClientBuilder apiClientBuilder()
{
return new DefaultApiClientBuilder();
}
}
Also, apiClientBuilder bean is not getting created.
The EKMSClientSdkConfiguration is extending ClientConfiguration, which is coming as part of another application jar. This class is not having any annotation.
public abstract class ClientConfiguration {
public ClientConfiguration()
{
}
public abstract void addSecurityProvider();
#Bean
public EKMSClient restClient() {
return new EKMSRestClientImpl(this.apiClient());
}
#Bean
public ApiClient apiClient() {
return Configuration.getDefaultApiClient();
}
}
In our case, EKMSClientSdkConfiguration bean is not getting created and the #PostConstruct is also not getting executed.
I went through the Spring Boot 2.2.RELEASE notes which is pointing to Spring Framework 5.2 upgrade guide. Here, I learned that spring boot 2.2.0 RELEASE is using Spring framework 5.2. In Spring framework 5.2, we have many changes.
It looks like this is the root cause of bean not getting loaded, but I am not sure about it.
Any help will be appreciated. Let me know if additional information is needed.
I found spring.main.lazy-initialization=true property in my application which was causing the above issue. When I removed it from the application.properties, This issue is resolved. This is the major change which was introduced in 2.2.0.RELEASE of spring boot

Spring Boot 2 Actuator without Spring Boot and #EnableAutoConfiguration

I am trying to set up Spring Actuator with existing Gradle Spring MVC project. I am not able to use #EnableAutoConfiguration.
Unfortunately, I am not able to reach actuator endpoints, I think I am missing something.
The Spring dependencies in the project are:
// springVersion = 5.1.+
implementation(
"org.springframework:spring-beans:$springVersion",
"org.springframework:spring-webmvc:$springVersion",
"org.springframework:spring-jdbc:$springVersion")
implementation 'org.springframework.boot:spring-boot-starter-actuator'
I am trying to configure project with following:
#Configuration
#Import({EndpointAutoConfiguration.class,
MetricsEndpointAutoConfiguration.class,
HealthEndpointAutoConfiguration.class,
MappingsEndpointAutoConfiguration.class,
InfoEndpointAutoConfiguration.class})
#EnableWebMvc
public class DI_App {
}
In properties file, I added:
management.endpoints.web.exposure.include=*
Non of actuator endpoints is enabled, I am getting 404 when trying to access them.
I went through many related questions, but non of the solutions worked for me.
I might need to define custom EndpointHandlerMapping but not sure how to do this, it seems unavailable.
(Ref: https://stackoverflow.com/a/53010693)
EDIT:
Currently, my app config looks like this:
#Configuration
#EnableWebMvc
#ComponentScan("com.test.springtest")
#Import({
ConfigurationPropertiesReportEndpointAutoConfiguration.class,
EndpointAutoConfiguration.class,
WebEndpointAutoConfiguration.class,
HealthEndpointAutoConfiguration.class,
HealthIndicatorAutoConfiguration.class,
InfoEndpointAutoConfiguration.class,
InfoContributorAutoConfiguration.class,
LogFileWebEndpointAutoConfiguration.class,
LoggersEndpointAutoConfiguration.class,
WebMvcMetricsAutoConfiguration.class,
ManagementWebSecurityAutoConfiguration.class,
ManagementContextAutoConfiguration.class,
ServletManagementContextAutoConfiguration.class
})
public class DI_App {
private final ApplicationContext _applicationContext;
DI_App(ApplicationContext applicationContext) {
_applicationContext = applicationContext;
System.setProperty("management.endpoints.web.exposure.include", "*");
System.setProperty("management.endpoints.jmx.exposure.exclude", "*");
System.setProperty("management.endpoints.web.base-path", "/manage");
System.setProperty("management.server.port", "10100");
}
#Bean
public WebMvcEndpointHandlerMapping endpointHandlerMapping(Collection<ExposableWebEndpoint> endpoints) {
List<String> mediaTypes = List.of(MediaType.APPLICATION_JSON_VALUE, ActuatorMediaType.V2_JSON);
EndpointMediaTypes endpointMediaTypes = new EndpointMediaTypes(mediaTypes, mediaTypes);
WebEndpointDiscoverer discoverer = new WebEndpointDiscoverer(_applicationContext,
new ConversionServiceParameterValueMapper(),
endpointMediaTypes,
List.of(EndpointId::toString),
emptyList(),
emptyList());
return new WebMvcEndpointHandlerMapping(new EndpointMapping("/manage"),
endpoints,
endpointMediaTypes,
new CorsConfiguration(),
new EndpointLinksResolver(discoverer.getEndpoints()));
}
}
I had to add dispatcherServlet bean, in order to be able to add ManagementContextAutoConfiguration.class to Imports:
#Component
public class AppDispatcherServlet implements DispatcherServletPath {
#Override
public String getPath() {
return "/";
}
}
Current state is that when going to /manage endpoint I get this:
{"_links":{"self":{"href":"http://localhost:10100/dev/manage","templated":false},"info":{"href":"http://localhost:10100/dev/manage/info","templated":false}}}
But http://localhost:10100/dev/manage/info returns 404 and no other endpoints are available.
I'm using Maven, not Gradle, but was in a similar situation. I had a working spring-boot-actuator 1.4.2.RELEASE Health actuator endpoint with Spring MVC 4.3.21. Upgraded to spring-boot-starter-actuator 2.6.1 and Spring MVC 5.3.13 and the following works for me to reach /myAppContext/health.
The DispatcherServletAutoConfiguration import may be able to replace your explicit DispatcherServlet bean. My case doesn't include the Info actuator endpoint but the key thing for me was the specific Imports below. Order is somewhat important for certain imports, at least in my testing.
I know very little about spring boot so this is the result of enabling auto configuration, pouring through spring boot TRACE log output, and trying lots of different import combinations.
#Configuration
#EnableWebMvc
#Import({
DispatcherServletAutoConfiguration.class,
WebMvcAutoConfiguration.class,
WebEndpointAutoConfiguration.class,
EndpointAutoConfiguration.class,
HealthEndpointAutoConfiguration.class,
WebMvcEndpointManagementContextConfiguration.class
})
#PropertySource("classpath:/health.properties")
public class MyAppActuatorConfig {
// 1.x version had EndpointHandlerMapping and HealthMvcEndpoint beans here.
// There may be a more spring-boot-ish way to get this done : )
}
And a minimal health.properties that suited my deployment specifics where security was already in place:
management.endpoints.web.base-path=/
management.endpoint.health.show-details=when-authorized
management.endpoint.health.show-components=when-authorized

Adding authorization to Annotation-driven swagger.json with Jersey 2 and Spring Boot

I'm trying to add Basic Authentication to Swagger UI for a to a Swagger-annotated Jersey 2.0 web service built with Spring Boot. I'm using:
Spring Boot 1.5.4
spring-boot-starter-jersey
Swagger UI 3.0.4
(Maven package) swagger-jersey2-jaxrs 1.5.13
I'm able to generate a swagger.json file with the following JerseyConfig and with Swagger annotations on my Resources. This article was immensely helpful in getting this far.
#Component
public class JerseyConfiguration extends ResourceConfig {
private static Log logger = LogFactory.getLog(JerseyConfiguration.class);
#Value("${spring.jersey.application-path:/}")
private String apiPath;
public JerseyConfiguration() {
registerEndpoints();
configureSwagger();
}
private void registerEndpoints() {
register(MyEndpoints.class);
// Generate Jersey WADL at /<Jersey's servlet path>/application.wadl
register(WadlResource.class);
// Lets us get to static content like swagger
property(ServletProperties.FILTER_STATIC_CONTENT_REGEX, "((/swagger/.*)|(.*\\.html))");
}
/**
* Configure the Swagger documentation for this API.
*/
private void configureSwagger() {
// Creates file at localhost:port/swagger.json
this.register(ApiListingResource.class);
this.register(SwaggerSerializers.class);
BeanConfig config = new BeanConfig();
config.setConfigId("example-jersey-app");
config.setTitle("Spring Boot + Jersey + Swagger");
config.setVersion("2");
config.setContact("Me <me#example.com>");
config.setSchemes(new String[] {"http", "https"});
config.setResourcePackage("com.example.api");
config.setBasePath(this.apiPath);
config.setPrettyPrint(true);
config.setScan(true);
}
}
Now I want to be able to use Basic Authentication to connect to these services from Swagger UI. I've configured it in Spring and can use it to authenticate to the site, but not from Swagger UI.
Unfortunately, none of the Spring Boot examples currently on the Swagger sample site include Jersey and authentication, and none of the Jersey examples use Spring Boot and #SpringBootApplication like I'm using on in my project.
How do I get Basic Auth to show up in the Swagger UI?
I was able to get this to work by adding ServletConfigAware to JerseyConfiguration. Then I could use the same style of Swagger configuration used in the Swagger Bootstrap.java examples.
#Component
public class JerseyConfiguration extends ResourceConfig implements ServletConfigAware{
private ServletConfig servletConfig;
// ... this is all unchanged ...
/**
* Configure the Swagger documentation for this API.
*/
private void configureSwagger() {
// Creates file at localhost:port/swagger.json
this.register(ApiListingResource.class);
this.register(SwaggerSerializers.class);
BeanConfig config = new BeanConfig();
// ... this is all unchanged ...
config.setScan(true);
Swagger swagger = new Swagger();
swagger.securityDefinition("basicAuth", new BasicAuthDefinition());
new SwaggerContextService().withServletConfig(servletConfig).updateSwagger(swagger);
}
#Override
public void setServletConfig(ServletConfig servletConfig) {
logger.info("Setting ServletConfig");
this.servletConfig = servletConfig;
}
}
After making these changes, and adding annotations like the following to my endpoints:
#Api(value = "/api", description = "My super API",
authorizations = {#Authorization(value="basicAuth")})
#Path("api")
#Component
public class MyApi {
I saw the following changes:
Added to my swagger.json:
"securityDefinitions":{"basicAuth":{"type":"basic"}}
...
"security":[{"basicAuth":[]}]}}
Also, in Swagger UI, a new green button appeared in the same row as the Schemes dropdown, that says "Authorize" with an open lock on it. If I click on it, a popup shows up where I can enter the username and password. Now those credentials are sent to the API when I use the Swagger UI "Try It" feature.

How to inject a Spring bean into a google cloud endpoint class?

I want to inject a Spring Data JpaRepository into a goodle cloud endpoint class.
How can I do this? Because I think currentliy the cloud endpoint class is not under Spring control and the autowired annotated repository remains always to null.
Some one found a solution for guice Appengine with Google Cloud Endpoints and Guice
What I want to do is the Same with Spring. So I want to bring up the cloud endpoints with the spring context.
Currently I do it over the Spring context to get my repositories like:
#Api(name = "myapi", version = "v1", scopes = { Constants.EMAIL_SCOPE }, clientIds = {
Constants.WEB_CLIENT_ID, Constants.ANDROID_CLIENT_ID,
Constants.IOS_CLIENT_ID, Constants.API_EXPLORER_CLIENT_ID }, audiences = {
Constants.ANDROID_AUDIENCE })
public class TestServiceImpl {
// #Autowired
private TestRepository repository;
public TestServiceImpl () {
repository = ApplicationContextProvider.getApplicationContext()
.getBean(TestRepository.class);
}
....
}
But I want to use Autowired, is that possible?
I encountered the same problem today. I found the solution by adding the following constructor:
public TestServiceImpl() {
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}
Hope it helps.

Resources