Skip to content

Commit

Permalink
fix(API): Use OIDC email claim instead of sub for auth
Browse files Browse the repository at this point in the history
  • Loading branch information
gnarea committed Sep 22, 2023
1 parent 1c6bcaa commit 94931ce
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 6 deletions.
2 changes: 1 addition & 1 deletion docs/api-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ This server exposes a RESTful API to manage VeraId organisations and the endpoin

## Authentication and authorisation

We use OAuth2 with JWKS to delegate authentication to an external identity provider. We require the JWT token's `sub` claim to be the email address of the user.
We use OAuth2 with JWKS to delegate authentication to an external identity provider. We require the JWT token to define the user's email address in the [OIDC `email` claim](https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims).

The API employs the following roles:

Expand Down
8 changes: 4 additions & 4 deletions src/api/orgAuthPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ interface OrgRequestParams {
}

interface AuthenticatedFastifyRequest extends FastifyRequest {
user: { sub: string };
user: { email: string };
}

interface AuthorisedFastifyRequest extends AuthenticatedFastifyRequest {
Expand Down Expand Up @@ -76,7 +76,7 @@ function registerOrgAuth(fastify: FastifyInstance, _opts: PluginMetadata, done:

fastify.addHook('onRequest', async (request, reply) => {
const superAdmin = envVar.get('AUTHORITY_SUPERADMIN').asString();
const userEmail = (request as AuthenticatedFastifyRequest).user.sub;
const userEmail = (request as AuthenticatedFastifyRequest).user.email;
const decision = await decideAuthorisation(userEmail, request, fastify.mongoose, superAdmin);
const reason = decision.didSucceed ? decision.result.reason : decision.context;
if (decision.didSucceed) {
Expand All @@ -102,11 +102,11 @@ const requireUserToBeAdmin: any = async (
reply: FastifyReply,
) => {
if (!request.isUserAdmin) {
await denyAuthorisation('User is not an admin', reply, request.user.sub);
await denyAuthorisation('User is not an admin', reply, request.user.email);
}
};

const orgAuthPlugin = fastifyPlugin(registerOrgAuth, { name: 'org-auth' });
export default orgAuthPlugin;

export { requireUserToBeAdmin };
export { type AuthenticatedFastifyRequest, requireUserToBeAdmin };
3 changes: 2 additions & 1 deletion src/testUtils/apiServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import type { PluginDone } from '../utilities/fastify/PluginDone.js';
import { HTTP_STATUS_CODES } from '../utilities/http.js';
import { MemberModelSchema, Role } from '../models/Member.model.js';
import type { Result, SuccessfulResult } from '../utilities/result.js';
import type { AuthenticatedFastifyRequest } from '../api/orgAuthPlugin.js';

import { makeTestServer, type TestServerFixture } from './server.js';
import { OAUTH2_JWKS_URL, OAUTH2_TOKEN_AUDIENCE, OAUTH2_TOKEN_ISSUER } from './authn.js';
Expand Down Expand Up @@ -83,7 +84,7 @@ function getMockAuthenticateFromServer(fastify: FastifyInstance) {
function setAuthUser(fastify: FastifyInstance, userEmail: string) {
// eslint-disable-next-line @typescript-eslint/require-await
getMockAuthenticateFromServer(fastify).mockImplementation(async (request) => {
(request as unknown as { user: { sub: string } }).user = { sub: userEmail };
(request as AuthenticatedFastifyRequest).user = { email: userEmail };
});
}

Expand Down

0 comments on commit 94931ce

Please sign in to comment.