This is an automated email from the ASF dual-hosted git repository.
rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-whiteboard.git
The following commit(s) were added to refs/heads/master by this push:
new 38c8e713 oidc-rp: replace some bespoke code with the Nimbus SDK
38c8e713 is described below
commit 38c8e713752dcc47fab5809a082989e9fe1cb2a9
Author: Robert Munteanu <[email protected]>
AuthorDate: Mon Jul 3 22:13:11 2023 +0300
oidc-rp: replace some bespoke code with the Nimbus SDK
---
.../servlets/oidc_rp/impl/OidcCallbackServlet.java | 84 +++++++++++-----------
1 file changed, 41 insertions(+), 43 deletions(-)
diff --git
a/org.apache.sling.servlets.oidc-rp/src/main/java/org/apache/sling/servlets/oidc_rp/impl/OidcCallbackServlet.java
b/org.apache.sling.servlets.oidc-rp/src/main/java/org/apache/sling/servlets/oidc_rp/impl/OidcCallbackServlet.java
index e8d6c886..341831fc 100644
---
a/org.apache.sling.servlets.oidc-rp/src/main/java/org/apache/sling/servlets/oidc_rp/impl/OidcCallbackServlet.java
+++
b/org.apache.sling.servlets.oidc-rp/src/main/java/org/apache/sling/servlets/oidc_rp/impl/OidcCallbackServlet.java
@@ -19,32 +19,21 @@ package org.apache.sling.servlets.oidc_rp.impl;
import static
org.osgi.service.component.annotations.ReferencePolicyOption.GREEDY;
import java.io.IOException;
-import java.io.StringReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLDecoder;
-import java.net.URLEncoder;
import java.net.http.HttpClient;
-import java.net.http.HttpRequest;
-import java.net.http.HttpRequest.BodyPublishers;
-import java.net.http.HttpResponse;
-import java.net.http.HttpResponse.BodyHandlers;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
-import javax.json.Json;
-import javax.json.JsonNumber;
-import javax.json.JsonObject;
-import javax.json.JsonReader;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
@@ -61,7 +50,16 @@ import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.nimbusds.oauth2.sdk.AccessTokenResponse;
+import com.nimbusds.oauth2.sdk.AuthorizationCode;
+import com.nimbusds.oauth2.sdk.AuthorizationCodeGrant;
import com.nimbusds.oauth2.sdk.ParseException;
+import com.nimbusds.oauth2.sdk.TokenErrorResponse;
+import com.nimbusds.oauth2.sdk.TokenRequest;
+import com.nimbusds.oauth2.sdk.TokenResponse;
+import com.nimbusds.oauth2.sdk.auth.ClientSecretBasic;
+import com.nimbusds.oauth2.sdk.auth.Secret;
+import com.nimbusds.oauth2.sdk.id.ClientID;
import com.nimbusds.openid.connect.sdk.AuthenticationErrorResponse;
import com.nimbusds.openid.connect.sdk.AuthenticationResponse;
import com.nimbusds.openid.connect.sdk.AuthenticationResponseParser;
@@ -105,6 +103,9 @@ public class OidcCallbackServlet extends
SlingAllMethodsServlet {
if ( response instanceof AuthenticationErrorResponse )
throw new
ServletException(authResponse.toErrorResponse().getErrorObject().toString());
+ Optional<String> redirect =
stateManager.getStateAttribute(authResponse.getState(),
OidcStateManager.PARAMETER_NAME_REDIRECT);
+ stateManager.unregisterState(authResponse.getState());
+
String authCode =
authResponse.toSuccessResponse().getAuthorizationCode().getValue();
Optional<String> desiredConnectionName =
stateManager.getStateAttribute(authResponse.getState(),
OidcStateManager.PARAMETER_NAME_CONNECTION);
@@ -124,42 +125,39 @@ public class OidcCallbackServlet extends
SlingAllMethodsServlet {
throw new ServletException("Misconfigured baseUrl");
// TODO - this code should be extracted and reused to refresh the
access token with a refresh token, if present
+ ClientID clientId = new ClientID(connection.clientId());
+ Secret clientSecret = new Secret(connection.clientSecret());
+ ClientSecretBasic clientCredentials = new
ClientSecretBasic(clientId, clientSecret);
+
+ AuthorizationCode code = new AuthorizationCode(authCode);
+
HttpClient client = HttpClient.newHttpClient();
Endpoints ep = Endpoints.discover(connection.baseUrl(), client);
+
+ TokenRequest tokenRequest = new TokenRequest(
+ new URI(ep.tokenEndpoint()),
+ clientCredentials,
+ new AuthorizationCodeGrant(code, new
URI(getCallbackUri(request)))
+ );
+
+ TokenResponse tokenResponse =
TokenResponse.parse(tokenRequest.toHTTPRequest().send());
+
+ if ( !tokenResponse.indicatesSuccess() ) {
+ TokenErrorResponse errorResponse =
tokenResponse.toErrorResponse();
+ logger.warn("Error returned when trying to obtain access token
: {}, {}",
+ errorResponse.getErrorObject().getCode(),
errorResponse.getErrorObject().getDescription());
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+ return;
+ }
+
+ AccessTokenResponse successResponse =
tokenResponse.toSuccessResponse();
- Map<String, String> params = new HashMap<>();
- params.put("client_id", connection.clientId());
- params.put("client_secret", connection.clientSecret());
- params.put("code", authCode);
- params.put("grant_type", "authorization_code");
- params.put("redirect_uri", getCallbackUri(request));
-
- String payload = params.entrySet().stream()
- .map( e -> e.getKey() + "="
+URLEncoder.encode(e.getValue(), StandardCharsets.UTF_8))
- .collect(Collectors.joining("&"));
-
- HttpRequest tokenRequest = HttpRequest.newBuilder()
- .uri(URI.create(ep.tokenEndpoint()))
- .headers("Content-Type",
"application/x-www-form-urlencoded")
- .POST(BodyPublishers.ofString(payload))
- .build();
-
- HttpResponse<String> tokenResponse = client.send(tokenRequest,
BodyHandlers.ofString());
- Optional<String> redirect =
stateManager.getStateAttribute(authResponse.getState(),
OidcStateManager.PARAMETER_NAME_REDIRECT);
- stateManager.unregisterState(authResponse.getState());
-
- String accessToken;
- String refreshToken = null;
+ String accessToken =
successResponse.getTokens().getAccessToken().getValue();
+ String refreshToken =
successResponse.getTokens().getRefreshToken().getValue();
ZonedDateTime expiry = null;
-
- try ( JsonReader reader = Json.createReader(new
StringReader(tokenResponse.body())) ) {
- JsonObject tokenObject = reader.readObject();
- accessToken = tokenObject.getString("access_token");
- JsonNumber expiresIn = tokenObject.getJsonNumber("expires_in");
- if ( expiresIn != null ) {
- expiry = LocalDateTime.now().plus(expiresIn.intValue(),
ChronoUnit.SECONDS).atZone(ZoneId.systemDefault());
- }
- refreshToken = tokenObject.getString("refresh_token", null);
+ long expiresIn =
successResponse.getTokens().getAccessToken().getLifetime();
+ if ( expiresIn > 0 ) {
+ expiry = LocalDateTime.now().plus(expiresIn,
ChronoUnit.SECONDS).atZone(ZoneId.systemDefault());
}
persister.persistToken(connection, request.getResourceResolver(),
accessToken, refreshToken, expiry);