Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add OAuth2redirectTest #1310

Draft
wants to merge 36 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
50afb3d
Test setup
christiangoerdes Oct 17, 2024
7e27c12
implemented simple test (WIP!).
christiangoerdes Oct 17, 2024
cbd9013
test extension (WIP)
christiangoerdes Oct 17, 2024
7ae6c3c
Add OAuth2 redirect test cases and update dependencies
t-burch Oct 23, 2024
354e296
Add URL decoding and response validation in OAuth2RedirectTest
christiangoerdes Oct 23, 2024
de57f31
Merge branch 'master' into OAuth2redirectTest
christiangoerdes Oct 24, 2024
ed0ee30
Improve OAuth2 redirect test functionality and enhance code clarity
t-burch Oct 24, 2024
7b42879
Merge remote-tracking branch 'origin/OAuth2redirectTest' into OAuth2r…
t-burch Oct 24, 2024
4cbea77
Implement OAuth2 flow enhancements and logging configuration
christiangoerdes Oct 24, 2024
a9ff3bd
WIP:
christiangoerdes Oct 24, 2024
8aa3071
.
t-burch Oct 30, 2024
81bf870
switched to relative path
christiangoerdes Oct 30, 2024
3f3c2ec
New consentfile
t-burch Oct 30, 2024
89b2d40
Finished OAuth2RedirectTest
christiangoerdes Oct 30, 2024
cee573f
refactoring
christiangoerdes Oct 30, 2024
f015128
Revert LogHelper tmp changes
christiangoerdes Oct 30, 2024
31f79e8
refactoring and code optimization
christiangoerdes Oct 30, 2024
64152a5
Merge branch 'master' into OAuth2redirectTest
rrayst Oct 31, 2024
a02fed0
Merge branch 'master' into OAuth2redirectTest
t-burch Nov 4, 2024
a96fc71
Merge branch 'master' into OAuth2redirectTest
t-burch Nov 6, 2024
6e4ace7
added check that URL survives encoding
rrayst Nov 7, 2024
ce7e28a
removed unnecessary file
rrayst Nov 7, 2024
b158620
First prototype of request continuation instead of redirection after …
t-burch Nov 8, 2024
55dbc3a
Add redirect handling in OAuth2CallbackRequestHandler and update OAut…
t-burch Nov 11, 2024
62d9808
Implement OAuth2 redirect handling in the doRedirect method
t-burch Nov 11, 2024
e68f5c7
Merge branch 'master' into OAuth2redirectTest
t-burch Nov 11, 2024
afcf054
Call the handler in OAuth2CallbackRequestHandler to process redirecti…
t-burch Nov 11, 2024
998fa57
Refactor OAuth2 redirect test to streamline steps for GET and POST re…
t-burch Nov 11, 2024
e71e139
Add assertion to verify URL encoding in OAuth2RedirectTest
t-burch Nov 11, 2024
669776b
Merge branch 'master' into OAuth2redirectTest
t-burch Dec 5, 2024
6632271
Merge branch 'master' into OAuth2redirectTest
rrayst Dec 9, 2024
97b73eb
Merge branch 'master' into OAuth2redirectTest
predic8 Dec 9, 2024
95b0262
Merge branch 'master' into OAuth2redirectTest
t-burch Dec 10, 2024
ac8f7a1
Refactor OAuth2 callback handling and update test cases
t-burch Dec 11, 2024
246afb0
Merge remote-tracking branch 'origin/OAuth2redirectTest' into OAuth2r…
t-burch Dec 11, 2024
60883a8
Merge branch 'master' into OAuth2redirectTest
rrayst Dec 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ private void parseSrc(InputStream resolve) throws IOException {

// without checks
tokenEndpoint = (String) json.get("token_endpoint");
if (tokenEndpoint == null)
throw new RuntimeException("No token_endpoint could be detected.");
userInfoEndpoint = (String) json.get("userinfo_endpoint");
authorizationEndpoint = (String) json.get("authorization_endpoint");
revocationEndpoint = (String) json.get("revocation_endpoint");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,15 @@
import org.jetbrains.annotations.NotNull;

import java.math.BigInteger;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Map;
import java.util.Optional;

import static com.predic8.membrane.core.interceptor.session.SessionManager.SESSION_VALUE_SEPARATOR;
import static java.nio.charset.StandardCharsets.UTF_8;

public class StateManager {

Expand All @@ -39,7 +42,7 @@ public static String getSecurityTokenFromState(String state2) {
if (state2 == null)
throw new RuntimeException("No CSRF token.");

Map<String, String> param = URLParamUtil.parseQueryString(state2, URLParamUtil.DuplicateKeyOrInvalidFormStrategy.ERROR);
Map<String, String> param = URLParamUtil.parseQueryString(URLDecoder.decode(state2, UTF_8), URLParamUtil.DuplicateKeyOrInvalidFormStrategy.ERROR);
rrayst marked this conversation as resolved.
Show resolved Hide resolved

if (!param.containsKey("security_token"))
throw new RuntimeException("No CSRF token.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.predic8.membrane.core.interceptor.RegExReplaceInterceptorTest;
import com.predic8.membrane.core.interceptor.rest.REST2SOAPInterceptorIntegrationTest;
import com.predic8.membrane.core.interceptor.server.WSDLPublisherTest;
import com.predic8.membrane.core.oauth2.OAuth2RedirectTest;
import com.predic8.membrane.core.resolver.ResolverTest;
import com.predic8.membrane.core.rules.ProxySSLTest;
import com.predic8.membrane.core.rules.SOAPProxyIntegrationTest;
Expand Down Expand Up @@ -47,7 +48,8 @@
IllegalCharactersInURLTest.class,
ProxySSLTest.class,
SessionManager.class,
OpenApiRewriteIntegrationTest.class
OpenApiRewriteIntegrationTest.class,
OAuth2RedirectTest.class
})
public class IntegrationTestsWithoutInternet {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
package com.predic8.membrane.core.oauth2;

import io.restassured.response.Response;
import org.jetbrains.annotations.NotNull;

import java.util.HashMap;
import java.util.Map;

import static io.restassured.RestAssured.given;
import static org.apache.http.HttpHeaders.LOCATION;
import static org.hamcrest.text.IsEqualIgnoringCase.equalToIgnoringCase;
import static org.hamcrest.text.MatchesPattern.matchesPattern;

public class OAuth2AuthFlowClient {

private static final String CLIENT_BASE_URL = "http://localhost:2000";
private static final String CLIENT_URL = CLIENT_BASE_URL + "/a?b=c&d= ";
private static final String AUTH_SERVER_URL = "http://localhost:2002";

static Map<String, String> cookies = new HashMap<>();
static Map<String, String> memCookies = new HashMap<>();

// @formatter:off
static @NotNull Response step1originalRequest() {
Response response =
given()
.redirects().follow(false)
.when()
.get(CLIENT_URL)
.then()
.statusCode(307)
.header(LOCATION, matchesPattern(AUTH_SERVER_URL + ".*"))
.extract().response();
memCookies.putAll(response.getCookies());
return response;
}

static @NotNull String step2sendAuthToOAuth2Server(Response response) {
Response formRedirect =
given()
.redirects().follow(false)
.cookies(cookies)
.urlEncodingEnabled(false)
.when()
.get(response.getHeader(LOCATION))
.then()
.statusCode(307)
.header(LOCATION, matchesPattern("/login.*"))
.extract().response();
cookies.putAll(formRedirect.getCookies());
return formRedirect.getHeader(LOCATION);
}

static void step3openLoginPage(String location) {
given()
.redirects().follow(true)
.cookies(cookies)
.when()
.get(AUTH_SERVER_URL + location)
.then()
.statusCode(200)
.extract().response();
}

static void step4submitLogin(String location) {
given()
.redirects().follow(false)
.cookies(cookies)
.header("Content-Type", "application/x-www-form-urlencoded")
.header("Accept-Charset", "UTF-8")
.formParam("username", "user")
.formParam("password", "password")
.when()
.post(AUTH_SERVER_URL + location)
.then()
.statusCode(200)
.header(LOCATION, "/")
.extract().response();
}

static String step5redirectToConsent() {
return given()
.redirects().follow(false)
.cookies(cookies)
.when()
.get(AUTH_SERVER_URL)
.then()
.statusCode(307)
.header(LOCATION, matchesPattern("/login/consent.*"))
.extract().response().getHeader(LOCATION);
}

static void step6openConsentDialog(String location) {
given()
.redirects().follow(false)
.cookies(cookies)
.when()
.get(AUTH_SERVER_URL + location)
.then()
.statusCode(200)
.extract().response();
}

static void step7submitConsent(String location) {
given()
.redirects().follow(false)
.cookies(cookies)
.header("Content-Type", "application/x-www-form-urlencoded")
.header("Accept-Charset", "UTF-8")
.formParam("consent", "Accept")
.when()
.post(AUTH_SERVER_URL + location)
.then()
.statusCode(200)
.header(LOCATION, "/")
.extract().response();
}

static String step8redirectToClient() {
return given()
.redirects().follow(false)
.cookies(cookies)
.when()
.post(AUTH_SERVER_URL)
.then()
.statusCode(307)
.header(LOCATION, matchesPattern(CLIENT_BASE_URL + ".*"))
.extract().response().getHeader(LOCATION);
}

static void step9exchangeCodeForToken(String location) {
given()
.redirects().follow(false)
.cookies(memCookies)
.when()
.post(location)
.then()
.statusCode(307)
.header(LOCATION, "/a?b=c&d=%20")
.extract().response();
}

static void step10makeAuthPostRequest() {
given()
.cookies(memCookies)
.when()
.post(CLIENT_URL)
.then()
.body(equalToIgnoringCase("get"));
}
// @formatter:on
}
Loading
Loading