Skip to content

Commit

Permalink
Fix cookie expiry issues from IDP/JWT auth methods, disables keepaliv…
Browse files Browse the repository at this point in the history
…e for JWT/IDP (#1773)



Signed-off-by: Derek Ho <dxho@amazon.com>
  • Loading branch information
derek-ho authored Feb 23, 2024
1 parent 4dc984b commit 0f1efc2
Show file tree
Hide file tree
Showing 16 changed files with 617 additions and 44 deletions.
4 changes: 4 additions & 0 deletions server/auth/types/authentication_type.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@
import { SecurityPluginConfigType } from '../..';
import { AuthenticationType } from './authentication_type';
import { httpServerMock } from '../../../../../src/core/server/mocks';
import { OpenSearchDashboardsRequest } from '../../../../../src/core/server';

class DummyAuthType extends AuthenticationType {
authNotRequired(request: OpenSearchDashboardsRequest): boolean {
return false;
}
buildAuthHeaderFromCookie() {}
getAdditionalAuthHeader() {}
handleUnauthedRequest() {}
Expand Down
14 changes: 13 additions & 1 deletion server/auth/types/authentication_type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ export abstract class AuthenticationType implements IAuthenticationType {

// extend session expiration time
if (this.config.session.keepalive) {
cookie!.expiryTime = Date.now() + this.config.session.ttl;
cookie!.expiryTime = this.getKeepAliveExpiry(cookie!, request);
this.sessionStorageFactory.asScoped(request).set(cookie!);
}
// cookie is valid
Expand Down Expand Up @@ -266,6 +266,13 @@ export abstract class AuthenticationType implements IAuthenticationType {
});
}

public getKeepAliveExpiry(
cookie: SecuritySessionCookie,
request: OpenSearchDashboardsRequest
): number {
return Date.now() + this.config.session.ttl;
}

isPageRequest(request: OpenSearchDashboardsRequest) {
const path = request.url.pathname || '/';
return path.startsWith('/app/') || path === '/' || path.startsWith('/goto/');
Expand All @@ -286,5 +293,10 @@ export abstract class AuthenticationType implements IAuthenticationType {
response: LifecycleResponseFactory,
toolkit: AuthToolkit
): IOpenSearchDashboardsResponse | AuthResult;
public abstract requestIncludesAuthInfo(request: OpenSearchDashboardsRequest): boolean;
public abstract buildAuthHeaderFromCookie(
cookie: SecuritySessionCookie,
request: OpenSearchDashboardsRequest
): any;
public abstract init(): Promise<void>;
}
69 changes: 69 additions & 0 deletions server/auth/types/basic/basic_auth.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright OpenSearch Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

import { httpServerMock } from '../../../../../../src/core/server/http/http_server.mocks';

import { SecurityPluginConfigType } from '../../../index';
import { SecuritySessionCookie } from '../../../session/security_cookie';
import {
IRouter,
CoreSetup,
ILegacyClusterClient,
Logger,
SessionStorageFactory,
} from '../../../../../../src/core/server';
import { BasicAuthentication } from './basic_auth';

describe('Basic auth tests', () => {
let router: IRouter;
let core: CoreSetup;
let esClient: ILegacyClusterClient;
let sessionStorageFactory: SessionStorageFactory<SecuritySessionCookie>;
let logger: Logger;

const config = {
session: {
ttl: 1000,
},
} as SecurityPluginConfigType;

test('getKeepAliveExpiry', () => {
const realDateNow = Date.now.bind(global.Date);
const dateNowStub = jest.fn(() => 0);
global.Date.now = dateNowStub;
const basicAuthentication = new BasicAuthentication(
config,
sessionStorageFactory,
router,
esClient,
core,
logger
);

const cookie: SecuritySessionCookie = {
credentials: {
authHeaderValueExtra: true,
},
expiryTime: 0,
};

const request = httpServerMock.createOpenSearchDashboardsRequest({
path: '/internal/v1',
});

expect(basicAuthentication.getKeepAliveExpiry(cookie, request)).toBe(1000);
global.Date.now = realDateNow;
});
});
5 changes: 4 additions & 1 deletion server/auth/types/basic/basic_auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,10 @@ export class BasicAuthentication extends AuthenticationType {
}
}

buildAuthHeaderFromCookie(cookie: SecuritySessionCookie): any {
buildAuthHeaderFromCookie(
cookie: SecuritySessionCookie,
request: OpenSearchDashboardsRequest
): any {
if (this.config.auth.anonymous_auth_enabled && cookie.isAnonymousAuth) {
return {};
}
Expand Down
14 changes: 13 additions & 1 deletion server/auth/types/jwt/jwt_auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {
getExtraAuthStorageValue,
setExtraAuthStorage,
} from '../../../session/cookie_splitter';
import { getExpirationDate } from './jwt_helper';

export const JWT_DEFAULT_EXTRA_STORAGE_OPTIONS: ExtraAuthStorageOptions = {
cookiePrefix: 'security_authentication_jwt',
Expand Down Expand Up @@ -154,13 +155,17 @@ export class JwtAuthentication extends AuthenticationType {
this.getBearerToken(request) || '',
this.getExtraAuthStorageOptions()
);

return {
username: authInfo.user_name,
credentials: {
authHeaderValueExtra: true,
},
authType: this.type,
expiryTime: Date.now() + this.config.session.ttl,
expiryTime: getExpirationDate(
this.getBearerToken(request),
Date.now() + this.config.session.ttl
),
};
}

Expand All @@ -175,6 +180,13 @@ export class JwtAuthentication extends AuthenticationType {
);
}

getKeepAliveExpiry(cookie: SecuritySessionCookie, request: OpenSearchDashboardsRequest): number {
return getExpirationDate(
this.buildAuthHeaderFromCookie(cookie, request)[this.authHeaderName],
Date.now() + this.config.session.ttl
);
}

handleUnauthedRequest(
request: OpenSearchDashboardsRequest,
response: LifecycleResponseFactory,
Expand Down
Loading

0 comments on commit 0f1efc2

Please sign in to comment.