Ability for Users to configure auth token expiration [19341]

Signed-off-by: Andy Muldoon <andy.muldoon@ericsson.com>
This commit is contained in:
Andy Muldoon
2023-12-22 13:58:07 +00:00
committed by Lavanya Sainik
parent b8e9eb3f73
commit 8e8a25dba5
7 changed files with 76 additions and 6 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-auth-backend': minor
---
Ability for user to configure backstage token expiration
+9
View File
@@ -165,3 +165,12 @@ To try out SAML, you can use the mock identity provider:
## Links
- [The Backstage homepage](https://backstage.io)
## Configuring Token Expiration in App Config
The expiration feature is not enabled unless you set this in your config file:
```
auth:
backstageTokenExpiration: { minutes: <user_defined_value> }
```
+6
View File
@@ -14,6 +14,8 @@
* limitations under the License.
*/
import { HumanDuration } from '@backstage/types';
export interface Config {
/** Configuration options for the auth plugin */
auth?: {
@@ -212,6 +214,10 @@ export interface Config {
cfaccess?: {
teamName: string;
};
/**
* The backstage token expiration.
*/
backstageTokenExpiration?: HumanDuration;
};
};
}
+1
View File
@@ -48,6 +48,7 @@
"@backstage/plugin-auth-backend-module-okta-provider": "workspace:^",
"@backstage/plugin-auth-node": "workspace:^",
"@backstage/plugin-catalog-node": "workspace:^",
"@backstage/types": "workspace:^",
"@google-cloud/firestore": "^7.0.0",
"@types/express": "^4.17.6",
"@types/passport": "^1.0.3",
@@ -15,7 +15,11 @@
*/
import { ConfigReader } from '@backstage/config';
import { createOriginFilter } from './router';
import {
createOriginFilter,
getDefaultBackstageTokenExpiryTime,
} from './router';
import { BACKSTAGE_SESSION_EXPIRATION } from '../lib/session';
describe('Auth origin filtering', () => {
const config = new ConfigReader({
@@ -52,3 +56,28 @@ describe('Auth origin filtering', () => {
expect(createOriginFilter(config)(origin)).toBeTruthy();
});
});
describe('Test for default backstage token expiry time', () => {
it('Will return default backstage session expiration', () => {
const config = new ConfigReader({
app: {
baseUrl: 'http://example.com/extra-path',
},
});
expect(getDefaultBackstageTokenExpiryTime(config)).toBe(
BACKSTAGE_SESSION_EXPIRATION,
);
});
it('Will return user defined backstage session expiration', () => {
const config = new ConfigReader({
app: {
baseUrl: 'http://example.com/extra-path',
},
auth: {
backstageTokenExpiration: { minutes: 120 },
},
});
expect(getDefaultBackstageTokenExpiryTime(config)).toBe(7200);
});
});
+24 -5
View File
@@ -29,7 +29,6 @@ import {
} from '@backstage/backend-common';
import { assertError, NotFoundError } from '@backstage/errors';
import { CatalogApi, CatalogClient } from '@backstage/catalog-client';
import { Config } from '@backstage/config';
import { createOidcRouter, TokenFactory, KeyStores } from '../identity';
import session from 'express-session';
import connectSessionKnex from 'connect-session-knex';
@@ -41,6 +40,8 @@ import { BACKSTAGE_SESSION_EXPIRATION } from '../lib/session';
import { TokenIssuer } from '../identity/types';
import { StaticTokenIssuer } from '../identity/StaticTokenIssuer';
import { StaticKeyStore } from '../identity/StaticKeyStore';
import { Config, readDurationFromConfig } from '@backstage/config';
import { durationToMilliseconds } from '@backstage/types';
/** @public */
export type ProviderFactories = { [s: string]: AuthProviderFactory };
@@ -76,9 +77,8 @@ export async function createRouter(
const appUrl = config.getString('app.baseUrl');
const authUrl = await discovery.getExternalBaseUrl('auth');
const backstageTokenExpiration = getDefaultBackstageTokenExpiryTime(config);
const authDb = AuthDatabase.create(database);
const sessionExpirationSeconds = BACKSTAGE_SESSION_EXPIRATION;
const keyStore = await KeyStores.fromConfig(config, {
logger,
@@ -91,7 +91,7 @@ export async function createRouter(
{
logger: logger.child({ component: 'token-factory' }),
issuer: authUrl,
sessionExpirationSeconds: sessionExpirationSeconds,
sessionExpirationSeconds: backstageTokenExpiration,
},
keyStore as StaticKeyStore,
);
@@ -99,7 +99,7 @@ export async function createRouter(
tokenIssuer = new TokenFactory({
issuer: authUrl,
keyStore,
keyDurationSeconds: sessionExpirationSeconds,
keyDurationSeconds: backstageTokenExpiration,
logger: logger.child({ component: 'token-factory' }),
algorithm:
tokenFactoryAlgorithm ??
@@ -249,3 +249,22 @@ export function createOriginFilter(
return allowedOriginPatterns.some(pattern => pattern.match(origin));
};
}
/** @internal */
export function getDefaultBackstageTokenExpiryTime(config: Config) {
const processingIntervalKey = 'auth.backstageTokenExpiration';
if (!config.has(processingIntervalKey)) {
return BACKSTAGE_SESSION_EXPIRATION;
}
const duration = readDurationFromConfig(config, {
key: processingIntervalKey,
});
const seconds = Math.max(
600,
Math.round(durationToMilliseconds(duration) / 1000),
);
return seconds;
}
+1
View File
@@ -4859,6 +4859,7 @@ __metadata:
"@backstage/plugin-auth-backend-module-okta-provider": "workspace:^"
"@backstage/plugin-auth-node": "workspace:^"
"@backstage/plugin-catalog-node": "workspace:^"
"@backstage/types": "workspace:^"
"@google-cloud/firestore": ^7.0.0
"@types/body-parser": ^1.19.0
"@types/cookie-parser": ^1.4.2