Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 3 additions & 1 deletion device-bound-session-credentials/login.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ def main(request, response):

test_session_manager = session_manager.find_for_request(request)

header_items = ["(RS256)",'challenge="login_challenge_value"',f'path="{registration_url}"']
header_items = ["(RS256)",f'path="{registration_url}"']
if test_session_manager.get_allows_challenges():
header_items.append('challenge="login_challenge_value"')
authorization_value = test_session_manager.get_authorization_value()
if authorization_value is not None:
header_items.append(f'authorization="{authorization_value}"')
Expand Down
10 changes: 5 additions & 5 deletions device-bound-session-credentials/refresh_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ def main(request, response):
if test_session_manager.get_has_custom_query_param() and 'refreshQueryParam' not in parse_qs(request.url_parts.query):
return (400, response.headers, "")

session_key = test_session_manager.get_session_key(session_id)
if session_key == None:
return (400, response.headers, "")

if test_session_manager.get_refresh_sends_challenge():
if test_session_manager.get_allows_challenges() and test_session_manager.get_refresh_sends_challenge():
challenge = "refresh_challenge_value"
if request.headers.get("Secure-Session-Response") == None:
return (403, [('Secure-Session-Challenge', f'"{challenge}";id="{session_id}"')], "")

session_key = test_session_manager.get_session_key(session_id)
if session_key == None:
return (400, response.headers, "")

jwt_header, jwt_payload, verified = jwt_helper.decode_jwt(request.headers.get("Secure-Session-Response").decode('utf-8'), session_key)

early_challenge = test_session_manager.get_early_challenge(session_id)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<meta charset="utf-8">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="helper.js" type="module"></script>

<script type="module">
import { expireCookie, waitForCookie, addCookieAndSessionCleanup, configureServer, setupShardedServerState, documentHasCookie } from "./helper.js";

promise_test(async t => {
await setupShardedServerState();
const expectedCookieAndValue = "auth_cookie=abcdef0123";
const expectedCookieAndAttributes = `${expectedCookieAndValue};Domain=${location.hostname};Path=/device-bound-session-credentials`;
addCookieAndSessionCleanup(t);

// Configure server to never send back a challenge.
await configureServer({
allowsChallenges: false
});

// Prompt starting a session, and wait until registration completes.
const loginResponse = await fetch('login.py');
assert_equals(loginResponse.status, 200);
await waitForCookie(expectedCookieAndValue, /*expectCookie=*/true);

// Confirm that expiring the cookie does refresh because registration succeeded.
expireCookie(expectedCookieAndAttributes);
assert_false(documentHasCookie(expectedCookieAndValue));
const authResponseAfterExpiry = await fetch('verify_authenticated.py');
assert_equals(authResponseAfterExpiry.status, 200);
assert_true(documentHasCookie(expectedCookieAndValue));
}, "Registration header doesn't need a challenge");
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def main(request, response):
challenges = []
for session_id in session_manager.find_for_request(request).get_session_ids():
early_challenge = test_session_manager.get_early_challenge(session_id)
if early_challenge is not None:
if test_session_manager.get_allows_challenges() and early_challenge is not None:
challenges.append(("Secure-Session-Challenge", f'"{early_challenge}";id="{session_id}"'))

if use_single_header:
Expand Down
8 changes: 8 additions & 0 deletions device-bound-session-credentials/session_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def __init__(self):
self.use_empty_response = False
self.registration_extra_cookies = []
self.has_custom_query_param = False
self.allows_challenges = True

def next_session_id(self):
return len(self.session_to_key_map)
Expand Down Expand Up @@ -169,6 +170,10 @@ def configure_state_for_test(self, configuration):
if has_custom_query_param is not None:
self.has_custom_query_param = has_custom_query_param

allows_challenges = configuration.get("allowsChallenges")
if allows_challenges is not None:
self.allows_challenges = allows_challenges

def get_should_refresh_end_session(self):
return self.should_refresh_end_session

Expand Down Expand Up @@ -276,3 +281,6 @@ def get_provider_url(self):

def get_provider_key(self):
return self.provider_key

def get_allows_challenges(self):
return self.allows_challenges
21 changes: 11 additions & 10 deletions device-bound-session-credentials/start_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,30 @@
def main(request, response):
test_session_manager = session_manager.find_for_request(request)
extra_cookie_headers = test_session_manager.get_set_cookie_headers(test_session_manager.registration_extra_cookies, request)
if test_session_manager.get_registration_sends_challenge_before_instructions():
if test_session_manager.get_allows_challenges() and test_session_manager.get_registration_sends_challenge_before_instructions():
# Only send back a challenge on the first call.
test_session_manager.reset_registration_sends_challenge_before_instructions()
return (403, [('Secure-Session-Challenge', '"login_challenge_value"')] + extra_cookie_headers, "")

jwt_header, jwt_payload, verified = jwt_helper.decode_jwt(request.headers.get("Secure-Session-Response").decode('utf-8'))
session_id = test_session_manager.create_new_session()
test_session_manager.set_session_key(session_id, jwt_header.get('jwk'))
if test_session_manager.get_allows_challenges():
jwt_header, jwt_payload, verified = jwt_helper.decode_jwt(request.headers.get("Secure-Session-Response").decode('utf-8'))
test_session_manager.set_session_key(session_id, jwt_header.get('jwk'))

if not verified or jwt_payload.get("jti") != "login_challenge_value":
return (400, list(response.headers) + extra_cookie_headers, "")
if not verified or jwt_payload.get("jti") != "login_challenge_value":
return (400, list(response.headers) + extra_cookie_headers, "")

if jwt_payload.get("authorization") != test_session_manager.get_authorization_value():
return (400, list(response.headers) + extra_cookie_headers, "")
if jwt_payload.get("authorization") != test_session_manager.get_authorization_value():
return (400, list(response.headers) + extra_cookie_headers, "")

if jwt_payload.get("sub") is not None:
return (400, list(response.headers) + extra_cookie_headers, "")
if jwt_payload.get("sub") is not None:
return (400, list(response.headers) + extra_cookie_headers, "")

if test_session_manager.get_has_custom_query_param() and 'registrationQueryParam' not in parse_qs(request.url_parts.query):
return (400, list(response.headers) + extra_cookie_headers, "")

(code, headers, body) = test_session_manager.get_session_instructions_response(session_id, request)
headers += extra_cookie_headers
if test_session_manager.get_registration_sends_challenge_with_instructions():
if test_session_manager.get_allows_challenges() and test_session_manager.get_registration_sends_challenge_with_instructions():
headers.append(('Secure-Session-Challenge', f'"login_challenge_value";id="{session_id}"'))
return (code, headers, body)