From 9cbb3cf908cfe1565afc4f65acf7cfb6815ed8ce Mon Sep 17 00:00:00 2001 From: Nataliya Issayeva Date: Wed, 10 Nov 2021 15:14:40 -0500 Subject: [PATCH] Remove auth middleware Signed-off-by: Nataliya Issayeva --- app-config.yaml | 1 + packages/app/src/App.tsx | 58 -------------------------- packages/backend/package.json | 2 - packages/backend/src/index.ts | 78 ----------------------------------- 4 files changed, 1 insertion(+), 138 deletions(-) diff --git a/app-config.yaml b/app-config.yaml index 88cd2c4648..d18b326c2c 100644 --- a/app-config.yaml +++ b/app-config.yaml @@ -23,6 +23,7 @@ app: title: '#backstage' backend: + # Used for enabling authorization, secret is shared by all backend plugins authorization: secret: ${BACKEND_SECRET} baseUrl: http://localhost:7000 diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx index 64a8163da2..401665b62e 100644 --- a/packages/app/src/App.tsx +++ b/packages/app/src/App.tsx @@ -86,52 +86,6 @@ import { providers } from './identityProviders'; import * as plugins from './plugins'; import { techDocsPage } from './components/techdocs/TechDocsPage'; -import { discoveryApiRef, useApi } from '@backstage/core-plugin-api'; - -// Parses supplied JWT token and returns the payload -function parseJwt(token: string): { exp: number } { - const base64Url = token.split('.')[1]; - const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/'); - const jsonPayload = decodeURIComponent( - atob(base64) - .split('') - .map(function (c) { - return `%${`00${c.charCodeAt(0).toString(16)}`.slice(-2)}`; - }) - .join(''), - ); - - return JSON.parse(jsonPayload); -} - -// Returns milliseconds until the supplied JWT token expires -function msUntilExpiry(token: string): number { - const payload = parseJwt(token); - const remaining = - new Date(payload.exp * 1000).getTime() - new Date().getTime(); - return remaining; -} - -// Calls the specified url regularly using an auth token to set a token cookie -// to authorize regular HTTP requests when loading techdocs -async function setTokenCookie(url: string, getIdToken: () => Promise) { - const token = await getIdToken(); - await fetch(url, { - mode: 'cors', - credentials: 'include', - headers: { - Authorization: `Bearer ${token}`, - }, - }); - // Call this function again a few minutes before the token expires - const ms = msUntilExpiry(token) - 4 * 60 * 1000; - setTimeout( - () => { - setTokenCookie(url, getIdToken); - }, - ms > 0 ? ms : 10000, - ); -} const app = createApp({ apis, @@ -142,24 +96,12 @@ const app = createApp({ }, components: { SignInPage: props => { - const discoveryApi = useApi(discoveryApiRef); return ( { - // When logged in, set a token cookie - if (typeof result.getIdToken !== 'undefined') { - setTokenCookie( - await discoveryApi.getBaseUrl('cookie'), - result.getIdToken, - ); - } - // Forward results - props.onResult(result); - }} /> ); }, diff --git a/packages/backend/package.json b/packages/backend/package.json index aa2e544386..4fb692f040 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -55,13 +55,11 @@ "@gitbeaker/node": "^30.2.0", "@octokit/rest": "^18.5.3", "azure-devops-node-api": "^11.0.1", - "cookie-parser": "^1.4.5", "dockerode": "^3.3.1", "example-app": "^0.2.53", "express": "^4.17.1", "express-promise-router": "^4.1.0", "express-prom-bundle": "^6.3.6", - "jose": "^1.27.1", "knex": "^0.95.1", "pg": "^8.3.0", "pg-connection-string": "^2.3.0", diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts index 171460e026..63285c83fa 100644 --- a/packages/backend/src/index.ts +++ b/packages/backend/src/index.ts @@ -34,7 +34,6 @@ import { UrlReaders, useHotMemoize, ServerTokenManager, - IdentityClient, } from '@backstage/backend-common'; import { Config } from '@backstage/config'; import healthcheck from './plugins/healthcheck'; @@ -57,10 +56,6 @@ import app from './plugins/app'; import badges from './plugins/badges'; import jenkins from './plugins/jenkins'; import { PluginEnvironment } from './types'; -import cookieParser from 'cookie-parser'; -import { Request, Response, NextFunction } from 'express'; -import { JWT } from 'jose'; -import { URL } from 'url'; function makeCreateEnv(config: Config) { const root = getRootLogger(); @@ -81,27 +76,6 @@ function makeCreateEnv(config: Config) { }; } -function setTokenCookie( - res: Response, - options: { token: string; secure: boolean; cookieDomain: string }, -) { - try { - const payload = JWT.decode(options.token) as object & { - exp: number; - }; - res.cookie(`token`, options.token, { - expires: new Date(payload?.exp ? payload?.exp * 1000 : 0), - secure: options.secure, - sameSite: 'lax', - domain: options.cookieDomain, - path: '/', - httpOnly: true, - }); - } catch (_err) { - // Ignore - } -} - async function main() { metricsInit(); const logger = getRootLogger(); @@ -140,59 +114,7 @@ async function main() { createEnv('tech-insights'), ); - const discovery = SingleHostDiscovery.fromConfig(config); - const identity = new IdentityClient({ - discovery, - issuer: await discovery.getExternalBaseUrl('auth'), - }); - const baseUrl = config.getString('backend.baseUrl'); - const secure = baseUrl.startsWith('https://'); - const cookieDomain = new URL(baseUrl).hostname; - const authMiddleware = async ( - req: Request, - res: Response, - next: NextFunction, - ) => { - try { - const token = - IdentityClient.getBearerToken(req.headers.authorization) || - req.cookies.token; - - const isServerToken = await authEnv.tokenManager.isServerToken(token); - if (!isServerToken) { - await identity.authenticate(token); - } - - if (!req.headers.authorization) { - // Authorization header may be forwarded by plugin requests - req.headers.authorization = `Bearer ${token}`; - } - if (token !== req.cookies.token) { - setTokenCookie(res, { - token, - secure, - cookieDomain, - }); - } - next(); - } catch (error) { - res.status(401).send(`Unauthorized`); - } - }; - const apiRouter = Router(); - apiRouter.use(cookieParser()); - // The auth route must be publically available as it is used during login - apiRouter.use('/auth', await auth(authEnv)); - // Add a simple endpoint to be used when setting a token cookie - apiRouter.use('/cookie', authMiddleware, (_req, res) => { - res.status(200).send(`Coming right up`); - }); - // Only authenticated requests are allowed to the routes below - apiRouter.use('/catalog', authMiddleware, await catalog(catalogEnv)); - apiRouter.use('/techdocs', authMiddleware, await techdocs(techdocsEnv)); - apiRouter.use('/proxy', authMiddleware, await proxy(proxyEnv)); - apiRouter.use(authMiddleware, notFoundHandler()); apiRouter.use('/catalog', await catalog(catalogEnv)); apiRouter.use('/code-coverage', await codeCoverage(codeCoverageEnv)); apiRouter.use('/rollbar', await rollbar(rollbarEnv));