@@ -25,94 +25,107 @@ exports.handler = (event, context, callback) => {
2525 const headers = request . headers || { } ;
2626 const query = request . querystring || '' ;
2727 const params = querystring . parse ( query ) ;
28- const providerKey = params . auth ;
28+ const authParam = params . auth ; // just for logging/debug
2929
30- console . log ( 'Edge Lambda - Query params:' , { providerKey } ) ;
30+ let providerKey = null ;
31+ console . log ( 'Edge Lambda - Query params:' , { authParam } ) ;
3132
32- // Extract session cookie
33+ // Extract session cookie & providerKey from cookies
3334 let session = null ;
3435 if ( headers . cookie && Array . isArray ( headers . cookie ) ) {
35- //console.log('Edge Lambda - Cookies:', headers.cookie);
3636 for ( const cookie of headers . cookie ) {
3737 const cookieValue = cookie . value || '' ;
38- //console.log('Edge Lambda - Processing cookie string:', cookieValue);
39- // Split cookies delimited by semicolon or space
4038 const cookieEntries = cookieValue . split ( '; ' ) . map ( entry => entry . trim ( ) ) ;
4139 for ( const entry of cookieEntries ) {
4240 if ( entry . startsWith ( 'session=' ) ) {
4341 session = entry . split ( '=' ) [ 1 ] ;
44- //console.log('Edge Lambda - Extracted session cookie:', session);
45- break ;
42+ } else if ( entry . startsWith ( 'auth_provider=' ) ) {
43+ providerKey = entry . split ( '=' ) [ 1 ] ;
4644 }
4745 }
48- if ( session ) break ;
46+ if ( session && providerKey ) break ;
4947 }
5048 } else {
5149 console . log ( 'Edge Lambda - No cookie header present or not an array' ) ;
5250 }
5351
52+ // Determine provider for this request
53+ // If providerKey not found in cookie, use query param ?auth=... or fallback to default
54+ let newlySelectedProviderKey = null ;
55+ if ( ! providerKey ) {
56+ newlySelectedProviderKey = params . auth || Object . keys ( config ) [ 0 ] ;
57+ providerKey = newlySelectedProviderKey ;
58+ console . log ( 'Edge Lambda - No auth_provider cookie, using query param or default:' , providerKey ) ;
59+ } else {
60+ console . log ( 'Edge Lambda - Using provider from cookie:' , providerKey ) ;
61+ }
62+
5463 // Validate session cookie if present
5564 if ( session ) {
56- //console.log('Edge Lambda - Found session cookie:', session);
57- // Check session cookie format (value.signature)
58- if ( ! session . includes ( '.' ) ) {
59- console . log ( 'Edge Lambda - Invalid session cookie format:' , session ) ;
65+ if ( ! providerKey || ! config [ providerKey ] ) {
66+ console . log ( 'Edge Lambda - Invalid or missing providerKey in config:' , providerKey ) ;
6067 } else {
61- const [ value , signature ] = session . split ( '.' ) ;
62- //console.log('Edge Lambda - Session cookie parts - Value:', value, 'Signature:', signature);
68+ const provider = config [ providerKey ] ;
6369
64- // Validate for selected provider if providerKey is present
65- if ( providerKey && config [ providerKey ] ) {
66- const provider = config [ providerKey ] ;
67- //console.log('Edge Lambda - Provider config:', JSON.stringify(provider, null, 2));
70+ // JWT-like format: value.signature
71+ if ( session . includes ( '.' ) ) {
72+ const [ value , signature ] = session . split ( '.' ) ;
6873 const expectedSignature = crypto
6974 . createHmac ( 'sha256' , provider . session_secret || '' )
7075 . update ( value )
7176 . digest ( 'hex' ) ;
7277 console . log ( 'Edge Lambda - Validating session for provider:' , providerKey ) ;
73- //console.log('Edge Lambda - Expected signature:', expectedSignature, 'Got:', signature);
7478 if ( signature === expectedSignature ) {
75- console . log ( 'Edge Lambda - Session validated successfully for provider:' , providerKey ) ;
76- return callback ( null , request ) ;
79+ try {
80+ const sessionJson = Buffer . from ( value , 'base64' ) . toString ( 'utf-8' ) ;
81+ const sessionPayload = JSON . parse ( sessionJson ) ;
82+ const now = Date . now ( ) ;
83+ if ( ! sessionPayload . exp || now < sessionPayload . exp ) {
84+ console . log ( 'Edge Lambda - Session validated successfully for provider:' , providerKey ) ;
85+ return callback ( null , request ) ;
86+ } else {
87+ console . log ( 'Edge Lambda - Session expired' ) ;
88+ }
89+ } catch ( err ) {
90+ console . log ( 'Edge Lambda - Failed to parse session payload:' , err . message ) ;
91+ console . log ( 'Edge Lambda - Accepting valid signature as opaque token' ) ;
92+ return callback ( null , request ) ;
93+ }
7794 } else {
7895 console . log ( 'Edge Lambda - Session validation failed for provider:' , providerKey ) ;
7996 }
8097 } else {
81- // Loop through providers if providerKey is not present
82- console . log ( 'Edge Lambda - No providerKey, trying all providers' ) ;
83- for ( const key of Object . keys ( config ) ) {
84- const provider = config [ key ] ;
85- //console.log('Edge Lambda - Provider config for', key, ':', JSON.stringify(provider, null, 2));
86- const expectedSignature = crypto
87- . createHmac ( 'sha256' , provider . session_secret || '' )
88- . update ( value )
89- . digest ( 'hex' ) ;
90- //console.log(`Edge Lambda - Validating session for provider: ${key}, Expected signature: ${expectedSignature}, Got: ${signature}`);
91- if ( signature === expectedSignature ) {
92- console . log ( 'Edge Lambda - Session validated successfully for provider:' , key ) ;
98+ // Opaque token: base64-encoded JSON
99+ try {
100+ const sessionJson = Buffer . from ( session , 'base64' ) . toString ( 'utf-8' ) ;
101+ const sessionPayload = JSON . parse ( sessionJson ) ;
102+ const now = Date . now ( ) ;
103+ if ( ! sessionPayload . exp || now < sessionPayload . exp ) {
104+ console . log ( 'Edge Lambda - Opaque session validated successfully for provider:' , providerKey ) ;
93105 return callback ( null , request ) ;
106+ } else {
107+ console . log ( 'Edge Lambda - Opaque session expired' ) ;
94108 }
109+ } catch ( err ) {
110+ console . log ( 'Edge Lambda - Failed to parse opaque session payload:' , err . message ) ;
95111 }
96- console . log ( 'Edge Lambda - Session validation failed for all providers' ) ;
97112 }
98113 }
99114 } else {
100115 console . log ( 'Edge Lambda - No session cookie found' ) ;
101116 }
102117
103118 // Redirect to OIDC if session is invalid or not present
104- //console.log('Edge Lambda - Config:', JSON.stringify(config, null, 2));
105- const defaultProviderKey = providerKey || Object . keys ( config ) [ 0 ] ;
106- if ( ! defaultProviderKey || ! config [ defaultProviderKey ] ) {
107- console . log ( 'Edge Lambda - No matching provider for:' , defaultProviderKey ) ;
119+ if ( ! providerKey || ! config [ providerKey ] ) {
120+ console . log ( 'Edge Lambda - No matching provider for:' , providerKey ) ;
108121 return callback ( null , {
109122 status : '403' ,
110123 statusDescription : 'Forbidden' ,
111124 body : 'No matching OIDC provider.' ,
112125 } ) ;
113126 }
114127
115- const provider = config [ defaultProviderKey ] ;
128+ const provider = config [ providerKey ] ;
116129 const state = crypto . randomBytes ( 16 ) . toString ( 'hex' ) ;
117130 const loginUrl = `${ provider . auth_url } ?` +
118131 `client_id=${ encodeURIComponent ( provider . client_id ) } ` +
@@ -122,6 +135,20 @@ exports.handler = (event, context, callback) => {
122135 console . log ( 'Edge Lambda - Redirecting to OIDC provider:' , loginUrl ) ;
123136 console . log ( 'Edge Lambda - Setting state cookie:' , state ) ;
124137
138+ // Prepare set-cookie headers
139+ const setCookieHeaders = [ {
140+ key : 'Set-Cookie' ,
141+ value : `state=${ state } ; Path=/; HttpOnly; Secure; SameSite=None; Max-Age=300` ,
142+ } ] ;
143+
144+ if ( newlySelectedProviderKey ) {
145+ const domain = new URL ( provider . redirect_after_login ) . hostname ;
146+ setCookieHeaders . push ( {
147+ key : 'Set-Cookie' ,
148+ value : `auth_provider=${ newlySelectedProviderKey } ; Path=/; HttpOnly; Secure; SameSite=None; Max-Age=300` ,
149+ } ) ;
150+ }
151+
125152 return callback ( null , {
126153 status : '302' ,
127154 statusDescription : 'Found' ,
@@ -130,10 +157,7 @@ exports.handler = (event, context, callback) => {
130157 key : 'Location' ,
131158 value : loginUrl ,
132159 } ] ,
133- 'set-cookie' : [ {
134- key : 'Set-Cookie' ,
135- value : `state=${ state } ; Path=/; HttpOnly; Secure; SameSite=None; Max-Age=300` ,
136- } ] ,
160+ 'set-cookie' : setCookieHeaders ,
137161 } ,
138162 } ) ;
139163 } catch ( error ) {
@@ -144,4 +168,4 @@ exports.handler = (event, context, callback) => {
144168 body : 'Edge Lambda failed to process the request' ,
145169 } ) ;
146170 }
147- } ;
171+ } ;
0 commit comments