Encode the authentication reject error to build a proper callback url (#568)
Encode the &error_code=access_denied query param for the callback url in order to fix the bug when the authentication request appears again if it was rejected.7.74.x
parent
00d8f7a858
commit
5b15aceef9
|
|
@ -12,6 +12,7 @@
|
|||
package org.eclipse.che.security.oauth;
|
||||
|
||||
import static com.google.common.base.Strings.isNullOrEmpty;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static java.util.Collections.emptyList;
|
||||
import static org.eclipse.che.commons.lang.UrlUtils.*;
|
||||
import static org.eclipse.che.commons.lang.UrlUtils.getParameter;
|
||||
|
|
@ -24,8 +25,10 @@ import jakarta.ws.rs.core.Response;
|
|||
import jakarta.ws.rs.core.UriBuilder;
|
||||
import jakarta.ws.rs.core.UriInfo;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.*;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
|
@ -84,9 +87,7 @@ public class EmbeddedOAuthAPI implements OAuthAPI, OAuthTokenFetcher {
|
|||
if (!isNullOrEmpty(redirectAfterLogin)
|
||||
&& errorValues != null
|
||||
&& errorValues.contains("access_denied")) {
|
||||
return Response.temporaryRedirect(
|
||||
URI.create(redirectAfterLogin + "&error_code=access_denied"))
|
||||
.build();
|
||||
return Response.temporaryRedirect(URI.create(encodeRedirectUrl())).build();
|
||||
}
|
||||
final String providerName = getParameter(params, "oauth_provider");
|
||||
OAuthAuthenticator oauth = getAuthenticator(providerName);
|
||||
|
|
@ -104,6 +105,23 @@ public class EmbeddedOAuthAPI implements OAuthAPI, OAuthTokenFetcher {
|
|||
return Response.temporaryRedirect(URI.create(redirectAfterLogin)).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the redirect URL query parameters to avoid the error when the redirect URL contains
|
||||
* JSON, as a query parameter. This prevents passing unsupported characters, like '{' and '}' to
|
||||
* the {@link URI#create(String)} method.
|
||||
*/
|
||||
private String encodeRedirectUrl() {
|
||||
try {
|
||||
URL url = new URL(redirectAfterLogin);
|
||||
String query = url.getQuery();
|
||||
return redirectAfterLogin.substring(0, redirectAfterLogin.indexOf(query))
|
||||
+ URLEncoder.encode(query + "&error_code=access_denied", UTF_8);
|
||||
} catch (MalformedURLException e) {
|
||||
LOG.error(e.getMessage(), e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<OAuthAuthenticatorDescriptor> getRegisteredAuthenticators(UriInfo uriInfo) {
|
||||
Set<OAuthAuthenticatorDescriptor> result = new HashSet<>();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2018 Red Hat, Inc.
|
||||
* Copyright (c) 2012-2023 Red Hat, Inc.
|
||||
* This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License 2.0
|
||||
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||
|
|
@ -11,6 +11,7 @@
|
|||
*/
|
||||
package org.eclipse.che.security.oauth;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.eclipse.che.dto.server.DtoFactory.newDto;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
|
|
@ -18,6 +19,10 @@ import static org.mockito.Mockito.mock;
|
|||
import static org.mockito.Mockito.when;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import jakarta.ws.rs.core.UriInfo;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.URI;
|
||||
import org.eclipse.che.api.auth.shared.dto.OAuthToken;
|
||||
import org.eclipse.che.api.core.NotFoundException;
|
||||
import org.mockito.InjectMocks;
|
||||
|
|
@ -54,4 +59,22 @@ public class EmbeddedOAuthAPITest {
|
|||
|
||||
assertEquals(result.getToken(), token);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldEncodeRejectErrorForRedirectUrl() throws Exception {
|
||||
// given
|
||||
UriInfo uriInfo = mock(UriInfo.class);
|
||||
when(uriInfo.getRequestUri()).thenReturn(new URI("http://eclipse.che"));
|
||||
Field redirectAfterLogin = EmbeddedOAuthAPI.class.getDeclaredField("redirectAfterLogin");
|
||||
redirectAfterLogin.setAccessible(true);
|
||||
redirectAfterLogin.set(embeddedOAuthAPI, "http://eclipse.che?quary=param");
|
||||
|
||||
// when
|
||||
Response callback = embeddedOAuthAPI.callback(uriInfo, singletonList("access_denied"));
|
||||
|
||||
// then
|
||||
assertEquals(
|
||||
callback.getLocation().toString(),
|
||||
"http://eclipse.che?quary%3Dparam%26error_code%3Daccess_denied");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue