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 JWT authentication type to MultipleAuthentication #2107

Merged
merged 18 commits into from
Oct 7, 2024
Merged
Changes from 1 commit
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
Prev Previous commit
Next Next commit
clarify comments in AuthenticationType.authHandler
Signed-off-by: merlinz01 <na@notaccessible.xyz>
  • Loading branch information
merlinz01 committed Aug 29, 2024
commit dcf8b8a9213a90e9e796e6c81e976da5b64d21ca
35 changes: 17 additions & 18 deletions server/auth/types/authentication_type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,77 +96,76 @@ export abstract class AuthenticationType implements IAuthenticationType {
}

public authHandler: AuthenticationHandler = async (request, response, toolkit) => {
// skip auth for APIs that do not require auth
// Skip authentication for APIs that do not require it
if (this.authNotRequired(request)) {
return toolkit.authenticated();
}

const authState: OpenSearchDashboardsAuthState = {};

// if browser request, auth logic is:
merlinz01 marked this conversation as resolved.
Show resolved Hide resolved
// 1. check if request includes auth header or parameter(e.g. jwt in url params) is present, if so, authenticate with auth header.
// 2. if auth header not present, check if auth cookie is present, if no cookie, send to authentication workflow
// 3. verify whether auth cookie is valid, if not valid, send to authentication workflow
// 4. if cookie is valid, pass to route handlers
const authHeaders = {};
let cookie: SecuritySessionCookie | null | undefined;
let authInfo: any | undefined;
// if this is an REST API call, suppose the request includes necessary auth header

// If the request contains authentication data (e.g. Authorization header or JWT in url parameters), use that to authenticate the request.
if (this.requestIncludesAuthInfo(request)) {
try {
// Build the auth headers from the request
const additionalAuthHeader = await this.getAdditionalAuthHeader(request);
Object.assign(authHeaders, additionalAuthHeader);
authInfo = await this.securityClient.authinfo(request, additionalAuthHeader);
cookie = this.getCookie(request, authInfo);

// set tenant from cookie if exist
// Set the tenant from the cookie
const browserCookie = await this.sessionStorageFactory.asScoped(request).get();
if (browserCookie && isValidTenant(browserCookie.tenant)) {
cookie.tenant = browserCookie.tenant;
}

// Save the cookie
this.sessionStorageFactory.asScoped(request).set(cookie);
} catch (error: any) {
return response.unauthorized({
body: error.message,
});
}
} else {
// no auth header in request, try cookie
// If the request does not contain authentication data, check for a stored cookie.
try {
cookie = await this.sessionStorageFactory.asScoped(request).get();
} catch (error: any) {
this.logger.error(`Error parsing cookie: ${error.message}`);
cookie = undefined;
}

// If the cookie is not valid, clear the cookie and send the request to the authentication workflow
if (!cookie || !(await this.isValidCookie(cookie, request))) {
// clear cookie
// Clear the cookie
this.sessionStorageFactory.asScoped(request).clear();

// for assets, we can still pass it to resource handler as notHandled.
// marking it as authenticated may result in login pop up when auth challenge
// For assets, we can still pass it to resource handler as notHandled.
// Marking it as authenticated may result in login pop up when auth challenge
// is enabled.
if (request.url.pathname && request.url.pathname.startsWith('/bundles/')) {
return toolkit.notHandled();
}

// allow optional authentication
// Allow optional authentication
if (this.authOptional(request)) {
return toolkit.authenticated();
}

// send to auth workflow
// Send the request to the authentication workflow
return this.handleUnauthedRequest(request, response, toolkit);
}

// extend session expiration time
// If the cookie is still valid, update the cookie with a new expiry time.
if (this.config.session.keepalive) {
cookie!.expiryTime = this.getKeepAliveExpiry(cookie!, request);
this.sessionStorageFactory.asScoped(request).set(cookie!);
}
// cookie is valid
// build auth header
// At this point we have a valid cookie.

// Build the auth headers from the cookie.
const authHeadersFromCookie = this.buildAuthHeaderFromCookie(cookie!, request);
Object.assign(authHeaders, authHeadersFromCookie);
const additionalAuthHeader = await this.getAdditionalAuthHeader(request);
Expand Down