diff --git a/pom.xml b/pom.xml
index 37ae5b8..3390132 100644
--- a/pom.xml
+++ b/pom.xml
@@ -50,31 +50,43 @@
- 1.8
- 1.8
+ 17
+ 17
- org.springframework.security.oauth
- spring-security-oauth2
- 2.3.5.RELEASE
+ org.springframework.security
+ spring-security-oauth2-client
+ 7.0.2
+
+
+
+ org.springframework.security
+ spring-security-core
+ 7.0.2
+
+
+
+ org.springframework.security
+ spring-security-web
+ 7.0.2
org.springframework
spring-web
- 5.1.1.RELEASE
+ 7.0.2
com.fasterxml.jackson.core
jackson-databind
- 2.10.3
+ 2.18.2
- javax.servlet
- javax.servlet-api
- 3.1.0
+ jakarta.servlet
+ jakarta.servlet-api
+ 6.0.0
diff --git a/src/main/java/io/fusionauth/security/FusionAuthUserDetails.java b/src/main/java/io/fusionauth/security/FusionAuthUserDetails.java
index 8789461..fcb3469 100644
--- a/src/main/java/io/fusionauth/security/FusionAuthUserDetails.java
+++ b/src/main/java/io/fusionauth/security/FusionAuthUserDetails.java
@@ -8,7 +8,7 @@
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.security.oauth2.common.OAuth2AccessToken;
+import org.springframework.security.oauth2.core.OAuth2AccessToken;
/**
* @author Tyler Scott
diff --git a/src/main/java/io/fusionauth/security/OpenIDAuthorizationCodeResourceDetails.java b/src/main/java/io/fusionauth/security/OpenIDAuthorizationCodeResourceDetails.java
deleted file mode 100644
index 9ef6e5b..0000000
--- a/src/main/java/io/fusionauth/security/OpenIDAuthorizationCodeResourceDetails.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package io.fusionauth.security;
-
-import org.springframework.security.oauth2.client.token.grant.code.AuthorizationCodeResourceDetails;
-
-/**
- * Extend the {@link AuthorizationCodeResourceDetails} to add the OpenID Connect UserInfo endpoint as described
- * in section 5.3 of OpenID Connect Core 1.0.
- *
- * @author Tyler Scott
- * @see https://openid.net/specs/openid-connect-core-1_0.html#UserInfo
- */
-public class OpenIDAuthorizationCodeResourceDetails extends AuthorizationCodeResourceDetails {
- private String userInfoUri;
-
- public String getUserInfoUri() {
- return userInfoUri;
- }
-
- public void settUserInfoUri(String userInfoUri) {
- this.userInfoUri = userInfoUri;
- }
-
-}
diff --git a/src/main/java/io/fusionauth/security/OpenIDConnectClientRegistration.java b/src/main/java/io/fusionauth/security/OpenIDConnectClientRegistration.java
new file mode 100644
index 0000000..e240d00
--- /dev/null
+++ b/src/main/java/io/fusionauth/security/OpenIDConnectClientRegistration.java
@@ -0,0 +1,38 @@
+package io.fusionauth.security;
+
+import org.springframework.security.oauth2.client.registration.ClientRegistration;
+
+/**
+ * Configuration class for OpenID Connect that holds client registration details
+ * and the OpenID Connect UserInfo endpoint as described in section 5.3
+ * of OpenID Connect Core 1.0.
+ *
+ * @author Tyler Scott
+ * @see https://openid.net/specs/openid-connect-core-1_0.html#UserInfo
+ */
+public class OpenIDConnectClientRegistration {
+ private ClientRegistration clientRegistration;
+ private String userInfoUri;
+
+ public OpenIDConnectClientRegistration(ClientRegistration clientRegistration, String userInfoUri) {
+ this.clientRegistration = clientRegistration;
+ this.userInfoUri = userInfoUri;
+ }
+
+ public ClientRegistration getClientRegistration() {
+ return clientRegistration;
+ }
+
+ public void setClientRegistration(ClientRegistration clientRegistration) {
+ this.clientRegistration = clientRegistration;
+ }
+
+ public String getUserInfoUri() {
+ return userInfoUri;
+ }
+
+ public void setUserInfoUri(String userInfoUri) {
+ this.userInfoUri = userInfoUri;
+ }
+
+}
diff --git a/src/main/java/io/fusionauth/security/OpenIDConnectFilter.java b/src/main/java/io/fusionauth/security/OpenIDConnectFilter.java
index dc6b733..496f447 100644
--- a/src/main/java/io/fusionauth/security/OpenIDConnectFilter.java
+++ b/src/main/java/io/fusionauth/security/OpenIDConnectFilter.java
@@ -1,7 +1,7 @@
package io.fusionauth.security;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import com.fasterxml.jackson.databind.JsonNode;
@@ -17,10 +17,11 @@
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
-import org.springframework.security.oauth2.client.OAuth2RestOperations;
-import org.springframework.security.oauth2.client.OAuth2RestTemplate;
-import org.springframework.security.oauth2.common.OAuth2AccessToken;
-import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
+import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
+import org.springframework.security.oauth2.client.OAuth2AuthorizedClientManager;
+import org.springframework.security.oauth2.client.OAuth2AuthorizeRequest;
+import org.springframework.security.oauth2.core.OAuth2AccessToken;
+import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.web.client.RestTemplate;
@@ -29,47 +30,58 @@
*/
public class OpenIDConnectFilter extends AbstractAuthenticationProcessingFilter {
@Autowired
- private OpenIDAuthorizationCodeResourceDetails openIDResourceDetails;
+ private OpenIDConnectClientRegistration openIDClientRegistration;
- private OAuth2RestOperations restTemplate;
+ private OAuth2AuthorizedClientManager authorizedClientManager;
- public OpenIDConnectFilter(String defaultFilterProcessesUrl) {
+ public OpenIDConnectFilter(String defaultFilterProcessesUrl, OAuth2AuthorizedClientManager authorizedClientManager) {
super(defaultFilterProcessesUrl);
+ this.authorizedClientManager = authorizedClientManager;
setAuthenticationManager(new NoopAuthenticationManager());
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
- OAuth2AccessToken accessToken;
- try {
- accessToken = restTemplate.getAccessToken();
- } catch (final OAuth2Exception e) {
- throw new BadCredentialsException("Could not obtain access token", e);
- }
try {
+ // Create OAuth2AuthorizeRequest for the registered client
+ OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest
+ .withClientRegistrationId(openIDClientRegistration.getClientRegistration().getRegistrationId())
+ .principal("anonymous") // For client credentials or similar flows
+ .build();
+
+ // Get the authorized client using the manager
+ OAuth2AuthorizedClient authorizedClient = authorizedClientManager.authorize(authorizeRequest);
+
+ if (authorizedClient == null) {
+ throw new BadCredentialsException("Could not authorize OAuth2 client");
+ }
+
+ OAuth2AccessToken accessToken = authorizedClient.getAccessToken();
FusionAuthUserDetails user = new FusionAuthUserDetails(getUserInfo(accessToken), accessToken);
return new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
+ } catch (OAuth2AuthenticationException e) {
+ throw new BadCredentialsException("Could not obtain access token", e);
} catch (Exception e) {
throw new BadCredentialsException("Failed to validate the token", e);
}
}
- public void setRestTemplate(OAuth2RestTemplate restTemplate2) {
- restTemplate = restTemplate2;
+ public void setAuthorizedClientManager(OAuth2AuthorizedClientManager authorizedClientManager) {
+ this.authorizedClientManager = authorizedClientManager;
}
private JsonNode getUserInfo(OAuth2AccessToken accessToken) throws IOException {
HttpHeaders headers = new HttpHeaders();
- headers.set("Authorization", "Bearer " + accessToken.getValue());
+ headers.set("Authorization", "Bearer " + accessToken.getTokenValue());
HttpEntity httpEntity = new HttpEntity<>(headers);
- ResponseEntity response = new RestTemplate().exchange(openIDResourceDetails.getUserInfoUri(), HttpMethod.GET, httpEntity, String.class);
+ ResponseEntity response = new RestTemplate().exchange(openIDClientRegistration.getUserInfoUri(), HttpMethod.GET, httpEntity, String.class);
if (response.getStatusCode() == HttpStatus.OK) {
return new ObjectMapper().readTree(response.getBody());
}
throw new BadCredentialsException("Failed to request user details from the UserInfo API. " +
- "Status code [" + response.getStatusCodeValue() + "] Message [" + response.getBody() + "]");
+ "Status code [" + response.getStatusCode().value() + "] Message [" + response.getBody() + "]");
}
private static class NoopAuthenticationManager implements AuthenticationManager {