Skip to content

Commit

Permalink
Add OAuth2 support for authentication with Solace PubSub+ Broker. (#133)
Browse files Browse the repository at this point in the history
* Add OAuth2 support for authentication with Solace PubSub+ Broker
* Disable overwrite settings in setup-java (#40)
* Updated dev docs.
* Fix action permissions (#41)
* fix manual test support install version
* Remove unwanted test dependency as requested in #101
Use slf4j instead of apache logging

---------

Co-authored-by: Jeffrey D <[email protected]>
  • Loading branch information
mayur-solace and Nephery authored Jul 18, 2024
1 parent 320892d commit 39febc5
Show file tree
Hide file tree
Showing 77 changed files with 6,373 additions and 201 deletions.
27 changes: 26 additions & 1 deletion .github/workflows/build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,23 @@ name: build
on:
pull_request:
push:
workflow_dispatch:

jobs:
build:
dupe_check:
name: Check for Duplicate Workflow Run
runs-on: ubuntu-latest
outputs:
should_skip: ${{ steps.skip_check.outputs.should_skip }}
steps:
- id: skip_check
uses: fkirc/[email protected]
with:
concurrent_skipping: same_content
do_not_skip: '["pull_request", "workflow_dispatch", "schedule"]'

build:
if: needs.dupe_check.outputs.should_skip != 'true'
runs-on: ubuntu-latest

steps:
Expand All @@ -18,7 +31,19 @@ jobs:
with:
distribution: 'zulu'
java-version: '17'
overwrite-settings: false
cache: 'maven'
- name: Manually Install Test Support If Necessary
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
run: |
sudo apt-get update -qq
sudo apt-get install -y libxml2-utils
version="$(xmllint --xpath '/*[local-name()="project"]/*[local-name()="properties"]/*[local-name()="solace.integration.test.support.version"]/text()' pom.xml)"
echo "Detected test support version: ${version}"
git clone --depth 1 --branch "${version}" https://github.com/SolaceDev/solace-integration-test-support.git
cd "${GITHUB_WORKSPACE}/solace-integration-test-support"
mvn install -Dchangelist= -DskipTests
- name: Build and run Tests
run: mvn clean verify --settings "${GITHUB_WORKSPACE}/maven/settings.xml"
env:
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ solace-spring-boot-build (root)
--> solace-java-sample-app
--> solace-jms-sample-app
--> solace-jms-sample-app-jndi
--> solace-java-oauth2-sample-app
Where:
<-- indicates the parent of the project
Expand Down
9 changes: 0 additions & 9 deletions maven/settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,5 @@
<username>${env.GITHUB_ACTOR}</username>
<password>${env.GITHUB_TOKEN}</password>
</server>
<server>
<id>ossrh</id>
<username>${env.MAVEN_OSSRH_USER}</username>
<password>${env.MAVEN_OSSRH_PASS}</password>
</server>
<server>
<id>gpg.passphrase</id>
<passphrase>${env.GPG_PASSPHRASE}</passphrase>
</server>
</servers>
</settings>
21 changes: 16 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<groupId>com.solace.spring.boot</groupId>
<artifactId>solace-spring-boot-build</artifactId>
<version>2.0.1-SNAPSHOT</version>
<version>2.1.0-SNAPSHOT</version>
<packaging>pom</packaging>

<name>Solace Spring Boot Build</name>
Expand All @@ -15,12 +15,14 @@
<repoName>SolaceProducts</repoName>

<!-- This is the version of Spring Boot we have targeted for this build -->
<spring.boot.version>3.0.6</spring.boot.version>
<spring.boot.version>3.3.1</spring.boot.version>

<solace.spring.boot.java-starter.version>5.0.1-SNAPSHOT
<solace.spring.boot.java-starter.version>5.1.0-SNAPSHOT
</solace.spring.boot.java-starter.version>
<solace.spring.boot.jms-starter.version>5.0.1-SNAPSHOT</solace.spring.boot.jms-starter.version>
<solace.spring.boot.starter.version>2.0.1-SNAPSHOT</solace.spring.boot.starter.version>
<solace.spring.boot.jms-starter.version>5.1.0-SNAPSHOT</solace.spring.boot.jms-starter.version>
<solace.spring.boot.starter.version>2.1.0-SNAPSHOT</solace.spring.boot.starter.version>
<testcontainers.version>1.19.8</testcontainers.version>
<solace.integration.test.support.version>1.1.2</solace.integration.test.support.version>
</properties>

<licenses>
Expand Down Expand Up @@ -54,6 +56,7 @@
<module>solace-spring-boot-samples/solace-java-sample-app</module>
<module>solace-spring-boot-samples/solace-jms-sample-app</module>
<module>solace-spring-boot-samples/solace-jms-sample-app-jndi</module>
<module>solace-spring-boot-samples/solace-java-oauth2-sample-app</module>
<module>solace-spring-boot-starters/solace-java-spring-boot-starter</module>
<module>solace-spring-boot-starters/solace-jms-spring-boot-starter</module>
<module>solace-spring-boot-starters/solace-spring-boot-starter</module>
Expand Down Expand Up @@ -85,6 +88,14 @@
<artifactId>solace-java-spring-boot-starter</artifactId>
<version>${solace.spring.boot.java-starter.version}</version>
</dependency>

<dependency>
<groupId>com.solace.test.integration</groupId>
<artifactId>solace-integration-test-support-bom</artifactId>
<version>${solace.integration.test.support.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
<parent>
<groupId>com.solace.spring.boot</groupId>
<artifactId>solace-spring-boot-parent</artifactId>
<version>2.0.1-SNAPSHOT</version>
<version>2.1.0-SNAPSHOT</version>
<relativePath>../../solace-spring-boot-parent/pom.xml</relativePath>
</parent>

<artifactId>solace-java-spring-boot-autoconfigure</artifactId>
<version>5.0.1-SNAPSHOT</version>
<version>5.1.0-SNAPSHOT</version>
<packaging>jar</packaging>

<name>Solace Spring Boot Autoconfiguration - Java</name>
Expand All @@ -34,16 +34,61 @@
<version>${solace.jcsmp.version}</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
<optional>true</optional>
</dependency>


<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.stefanbirkner</groupId>
<artifactId>system-rules</artifactId>
<version>1.19.0</version>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit-pioneer</groupId>
<artifactId>junit-pioneer</artifactId>
<version>1.9.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>${testcontainers.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<version>${testcontainers.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.solace.test.integration</groupId>
<artifactId>pubsubplus-junit-jupiter</artifactId>
<version>${solace.integration.test.support.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>${testcontainers.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import com.solacesystems.jcsmp.JCSMPChannelProperties;
import com.solacesystems.jcsmp.JCSMPProperties;
import com.solacesystems.jcsmp.SolaceSessionOAuth2TokenProvider;
import com.solacesystems.jcsmp.SpringJCSMPFactory;
import java.util.Map;
import java.util.Map.Entry;
Expand All @@ -33,12 +34,15 @@
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.lang.Nullable;

@Configuration
@AutoConfigureBefore(JmsAutoConfiguration.class)
@ConditionalOnClass({JCSMPProperties.class})
@ConditionalOnMissingBean(SpringJCSMPFactory.class)
@EnableConfigurationProperties(SolaceJavaProperties.class)
@Import(SolaceOAuthClientConfiguration.class)
public class SolaceJavaAutoConfiguration {

private SolaceJavaProperties properties;
Expand All @@ -54,8 +58,9 @@ public SolaceJavaAutoConfiguration(SolaceJavaProperties properties) {
* @return {@link SpringJCSMPFactory} based on {@link JCSMPProperties} bean.
*/
@Bean
public SpringJCSMPFactory getSpringJCSMPFactory(JCSMPProperties jcsmpProperties) {
return new SpringJCSMPFactory(jcsmpProperties);
public SpringJCSMPFactory getSpringJCSMPFactory(JCSMPProperties jcsmpProperties,
@Nullable SolaceSessionOAuth2TokenProvider solaceSessionOAuth2TokenProvider) {
return new SpringJCSMPFactory(jcsmpProperties, solaceSessionOAuth2TokenProvider);
}

/**
Expand Down Expand Up @@ -87,6 +92,12 @@ public JCSMPProperties getJCSMPProperties() {
cp.setReconnectRetries(properties.getReconnectRetries());
cp.setConnectRetriesPerHost(properties.getConnectRetriesPerHost());
cp.setReconnectRetryWaitInMillis(properties.getReconnectRetryWaitInMillis());

if (properties.getOauth2ClientRegistrationId() != null) {
jcsmpProps.setProperty(SolaceJavaProperties.SPRING_OAUTH2_CLIENT_REGISTRATION_ID,
properties.getOauth2ClientRegistrationId());
}

return jcsmpProps;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
@ConfigurationProperties("solace.java")
public class SolaceJavaProperties {

public static final String SPRING_OAUTH2_CLIENT_REGISTRATION_ID = "SPRING_OAUTH2_CLIENT_REGISTRATION_ID";

/**
* Solace Message Router Host address. Port is optional and intelligently defaulted by the Solace Java API.
*/
Expand Down Expand Up @@ -99,7 +101,22 @@ public class SolaceJavaProperties {
*/
private final Map<String,String> apiProperties = new ConcurrentHashMap<>();

/**
* The Spring Security OAuth2 Client Registration Id
* <code>spring.security.oauth2.client.registration.&lt;registration-id&gt;</code> to use for OAuth2
* token
* retrieval. This field is required when the Solace session is configured to use OAuth2 via
* <code>solace.java.apiProperties.authentication_scheme=AUTHENTICATION_SCHEME_OAUTH2</code>
*/
private String oauth2ClientRegistrationId;

public String getOauth2ClientRegistrationId() {
return oauth2ClientRegistrationId;
}

public void setOauth2ClientRegistrationId(String oauth2ClientRegistrationId) {
this.oauth2ClientRegistrationId = oauth2ClientRegistrationId;
}

public String getHost() {
return host;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package com.solace.spring.boot.autoconfigure;

import com.solacesystems.jcsmp.DefaultSolaceSessionOAuth2TokenProvider;
import com.solacesystems.jcsmp.JCSMPProperties;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.security.oauth2.client.AuthorizedClientServiceOAuth2AuthorizedClientManager;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProvider;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientProviderBuilder;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;

/**
* Configuration class for Solace OAuth client. This configuration is only active when the
* 'solace.java.apiProperties.AUTHENTICATION_SCHEME' property is set to
* 'AUTHENTICATION_SCHEME_OAUTH2'.
*/
@Configuration
@ConditionalOnProperty(prefix = "solace.java.apiProperties", name = "AUTHENTICATION_SCHEME",
havingValue = "AUTHENTICATION_SCHEME_OAUTH2")
@Import(OAuth2ClientAutoConfiguration.class)
public class SolaceOAuthClientConfiguration {

/**
* Creates and configures an OAuth2AuthorizedClientManager for Solace session. This manager is
* configured with OAuth2AuthorizedClientProvider for client credentials and refresh token.
*
* @param clientRegistrationRepository Repository of client registrations.
* @param oAuth2AuthorizedClientService Service for authorized OAuth2 clients.
* @return Configured OAuth2AuthorizedClientManager.
*/
@Bean
public AuthorizedClientServiceOAuth2AuthorizedClientManager solaceOAuthAuthorizedClientServiceAndManager(
ClientRegistrationRepository clientRegistrationRepository,
OAuth2AuthorizedClientService oAuth2AuthorizedClientService) {
final OAuth2AuthorizedClientProvider clientCredentialsAuthorizedClientProvider =
OAuth2AuthorizedClientProviderBuilder.builder()
.authorizationCode()
.clientCredentials()
.refreshToken()
.build();

final AuthorizedClientServiceOAuth2AuthorizedClientManager authorizedClientManager =
new AuthorizedClientServiceOAuth2AuthorizedClientManager(
clientRegistrationRepository, oAuth2AuthorizedClientService);
authorizedClientManager.setAuthorizedClientProvider(clientCredentialsAuthorizedClientProvider);

return authorizedClientManager;
}

/**
* Creates a SolaceSessionOAuth2TokenProvider for providing OAuth2 access tokens for Solace
* sessions.
*
* @param jcsmpProperties The JCSMP properties.
* @param solaceOAuthAuthorizedClientServiceAndManager The OAuth2AuthorizedClientManager for
* Solace session.
* @return Configured SolaceSessionOAuth2TokenProvider.
*/
@Bean
public DefaultSolaceSessionOAuth2TokenProvider solaceSessionOAuth2TokenProvider(
JCSMPProperties jcsmpProperties,
AuthorizedClientServiceOAuth2AuthorizedClientManager solaceOAuthAuthorizedClientServiceAndManager) {
return new DefaultSolaceSessionOAuth2TokenProvider(jcsmpProperties,
solaceOAuthAuthorizedClientServiceAndManager);
}
}
Loading

0 comments on commit 39febc5

Please sign in to comment.