in src/main/java/org/apache/sling/auth/oauth_client/impl/OidcAuthenticationHandler.java [180:245]
public AuthenticationInfo extractCredentials(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response) {
logger.debug("inside extractCredentials");
// Check if the request is authenticated by a oidc login token
AuthenticationInfo authInfo = loginCookieManager.verifyLoginCookie(request);
if (authInfo != null) {
// User has a login token
return authInfo;
}
//The request is not authenticated.
// 1. Check if the State cookie match with the state in the request received from the idp
StringBuffer requestURL = request.getRequestURL();
if ( request.getQueryString() != null )
requestURL.append('?').append(request.getQueryString());
Optional<OAuthState> clientState; //state returned by the idp in the redirect request
String authCode; //authorization code returned by the idp in the redirect request
Cookie stateCookie;
try {
AuthorizationResponse authResponse = AuthorizationResponse.parse(new URI(requestURL.toString()));
clientState = extractClientState(authResponse);
authCode = extractAuthCode(authResponse);
stateCookie = extractStateCookie(request);
} catch (ParseException | URISyntaxException e) {
logger.debug("Failed to parse authorization response");
return null;
}
String stateFromAuthServer = clientState.get().perRequestKey();
String stateFromClient = stateCookie.getValue();
if (!stateFromAuthServer.equals(stateFromClient)) {
throw new IllegalStateException("Failed state check: request keys from client and server are not the same");
}
// 2. The state cookie is valid, we can exchange an authorization code for an access token
Optional<String> redirect = Optional.ofNullable(clientState.get().redirect());
// TODO: find a better way to pass it?
request.setAttribute(REDIRECT_ATTRIBUTE_NAME,redirect);
String desiredConnectionName = clientState.get().connectionName();
ClientConnection connection = connections.get(desiredConnectionName);
if (connection == null) {
throw new IllegalArgumentException(String.format("Requested unknown connection '%s'", desiredConnectionName));
}
ResolvedOidcConnection conn = ResolvedOidcConnection.resolve(connection);
ClientID clientId = new ClientID(conn.clientId());
Secret clientSecret = new Secret(conn.clientSecret());
ClientSecretBasic clientCredentials = new ClientSecretBasic(clientId, clientSecret);
// Exchange the authorization code for an access token, id token and possibly refresh token
TokenResponse tokenResponse = extractTokenResponse(authCode, conn, clientCredentials, callbackUri);
IDTokenClaimsSet claims = validateIdToken(tokenResponse, conn);
// Make the request to userInfo
String subject = claims.getSubject().getValue();
OidcAuthCredentials credentials = extractCredentials((OidcConnectionImpl) connection, subject, tokenResponse);
//create authInfo
authInfo = new AuthenticationInfo(AUTH_TYPE, subject);
authInfo.put(JcrResourceConstants.AUTHENTICATION_INFO_CREDENTIALS, credentials);
logger.info("User {} authenticated", subject);
return authInfo;
}