auth-backend: slim down oauth start interface and allow for state modifications

This commit is contained in:
Patrik Oldsberg
2020-09-05 13:42:58 +02:00
parent 32a23a761d
commit 9e07bdb43d
10 changed files with 64 additions and 61 deletions
@@ -24,9 +24,9 @@ import {
} from '../../providers/types';
import { InputError } from '@backstage/backend-common';
import { TokenIssuer } from '../../identity';
import { verifyNonce, encodeState } from './helpers';
import { verifyNonce } from './helpers';
import { postMessageResponse, ensuresXRequestedWith } from '../flow';
import { OAuthHandlers } from './types';
import { OAuthHandlers, OAuthStartRequest } from './types';
export const THOUSAND_DAYS_MS = 1000 * 24 * 60 * 60 * 1000;
export const TEN_MINUTES_MS = 600 * 1000;
@@ -86,15 +86,12 @@ export class OAuthAdapter implements AuthProviderRouteHandlers {
// set a nonce cookie before redirecting to oauth provider
this.setNonceCookie(res, nonce);
const stateObject = { nonce: nonce, env: env };
const stateParameter = encodeState(stateObject);
const state = { nonce: nonce, env: env };
const forwardReq = Object.assign(req, { scope, state });
const queryParameters = {
scope,
state: stateParameter,
};
const { url, status } = await this.handlers.start(req, queryParameters);
const { url, status } = await this.handlers.start(
forwardReq as OAuthStartRequest,
);
res.statusCode = status || 302;
res.setHeader('Location', url);
@@ -16,10 +16,12 @@
export { OAuthEnvironmentHandler } from './OAuthEnvironmentHandler';
export { OAuthAdapter } from './OAuthAdapter';
export { encodeState } from './helpers';
export type {
OAuthHandlers,
OAuthProviderInfo,
OAuthProviderOptions,
OAuthResponse,
OAuthState,
OAuthStartRequest,
} from './types';
+6 -4
View File
@@ -67,6 +67,11 @@ export type OAuthState = {
env: string;
};
export type OAuthStartRequest = express.Request<{}> & {
scope: string;
state: OAuthState;
};
/**
* Any OAuth provider needs to implement this interface which has provider specific
* handlers for different methods to perform authentication, get access tokens,
@@ -78,10 +83,7 @@ export interface OAuthHandlers {
* @param {express.Request} req
* @param options
*/
start(
req: express.Request,
options: Record<string, string>,
): Promise<RedirectInfo>;
start(req: OAuthStartRequest): Promise<RedirectInfo>;
/**
* Handles the redirect from the auth provider when the user has signed in.
@@ -23,6 +23,8 @@ import {
OAuthHandlers,
OAuthResponse,
OAuthEnvironmentHandler,
OAuthStartRequest,
encodeState,
} from '../../lib/oauth';
import {
executeFetchUserProfileStrategy,
@@ -81,16 +83,13 @@ export class Auth0AuthProvider implements OAuthHandlers {
);
}
async start(
req: express.Request,
options: Record<string, string>,
): Promise<RedirectInfo> {
const providerOptions = {
...options,
async start(req: OAuthStartRequest): Promise<RedirectInfo> {
return await executeRedirectStrategy(req, this._strategy, {
accessType: 'offline',
prompt: 'consent',
};
return await executeRedirectStrategy(req, this._strategy, providerOptions);
scope: req.scope,
state: encodeState(req.state),
});
}
async handler(
@@ -29,6 +29,8 @@ import {
OAuthHandlers,
OAuthResponse,
OAuthEnvironmentHandler,
OAuthStartRequest,
encodeState,
} from '../../lib/oauth';
import passport from 'passport';
@@ -117,11 +119,11 @@ export class GithubAuthProvider implements OAuthHandlers {
);
}
async start(
req: express.Request,
options: Record<string, string>,
): Promise<RedirectInfo> {
return await executeRedirectStrategy(req, this._strategy, options);
async start(req: OAuthStartRequest): Promise<RedirectInfo> {
return await executeRedirectStrategy(req, this._strategy, {
scope: req.scope,
state: encodeState(req.state),
});
}
async handler(req: express.Request) {
@@ -29,6 +29,8 @@ import {
OAuthHandlers,
OAuthResponse,
OAuthEnvironmentHandler,
OAuthStartRequest,
encodeState,
} from '../../lib/oauth';
import passport from 'passport';
@@ -122,11 +124,11 @@ export class GitlabAuthProvider implements OAuthHandlers {
);
}
async start(
req: express.Request,
options: Record<string, string>,
): Promise<RedirectInfo> {
return await executeRedirectStrategy(req, this._strategy, options);
async start(req: OAuthStartRequest): Promise<RedirectInfo> {
return await executeRedirectStrategy(req, this._strategy, {
scope: req.scope,
state: encodeState(req.state),
});
}
async handler(req: express.Request): Promise<{ response: OAuthResponse }> {
@@ -31,6 +31,8 @@ import {
OAuthProviderOptions,
OAuthResponse,
OAuthEnvironmentHandler,
OAuthStartRequest,
encodeState,
} from '../../lib/oauth';
import passport from 'passport';
@@ -79,16 +81,13 @@ export class GoogleAuthProvider implements OAuthHandlers {
);
}
async start(
req: express.Request,
options: Record<string, string>,
): Promise<RedirectInfo> {
const providerOptions = {
...options,
async start(req: OAuthStartRequest): Promise<RedirectInfo> {
return await executeRedirectStrategy(req, this._strategy, {
accessType: 'offline',
prompt: 'consent',
};
return await executeRedirectStrategy(req, this._strategy, providerOptions);
scope: req.scope,
state: encodeState(req.state),
});
}
async handler(
@@ -35,6 +35,8 @@ import {
OAuthHandlers,
OAuthResponse,
OAuthEnvironmentHandler,
OAuthStartRequest,
encodeState,
} from '../../lib/oauth';
import got from 'got';
@@ -111,11 +113,11 @@ export class MicrosoftAuthProvider implements OAuthHandlers {
);
}
async start(
req: express.Request,
options: Record<string, string>,
): Promise<RedirectInfo> {
return await executeRedirectStrategy(req, this._strategy, options);
async start(req: OAuthStartRequest): Promise<RedirectInfo> {
return await executeRedirectStrategy(req, this._strategy, {
scope: req.scope,
state: encodeState(req.state),
});
}
async handler(
@@ -23,6 +23,8 @@ import {
OAuthHandlers,
OAuthResponse,
OAuthEnvironmentHandler,
OAuthStartRequest,
encodeState,
} from '../../lib/oauth';
import {
executeFetchUserProfileStrategy,
@@ -84,16 +86,13 @@ export class OAuth2AuthProvider implements OAuthHandlers {
);
}
async start(
req: express.Request,
options: Record<string, string>,
): Promise<RedirectInfo> {
const providerOptions = {
...options,
async start(req: OAuthStartRequest): Promise<RedirectInfo> {
return await executeRedirectStrategy(req, this._strategy, {
accessType: 'offline',
prompt: 'consent',
};
return await executeRedirectStrategy(req, this._strategy, providerOptions);
scope: req.scope,
state: encodeState(req.state),
});
}
async handler(
@@ -20,6 +20,8 @@ import {
OAuthHandlers,
OAuthResponse,
OAuthEnvironmentHandler,
OAuthStartRequest,
encodeState,
} from '../../lib/oauth';
import { Strategy as OktaStrategy } from 'passport-okta-oauth';
import passport from 'passport';
@@ -101,16 +103,13 @@ export class OktaAuthProvider implements OAuthHandlers {
);
}
async start(
req: express.Request,
options: Record<string, string>,
): Promise<RedirectInfo> {
const providerOptions = {
...options,
async start(req: OAuthStartRequest): Promise<RedirectInfo> {
return await executeRedirectStrategy(req, this._strategy, {
accessType: 'offline',
prompt: 'consent',
};
return await executeRedirectStrategy(req, this._strategy, providerOptions);
scope: req.scope,
state: encodeState(req.state),
});
}
async handler(