0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-02-17 22:04:19 -05:00

fix(core): koaAuth should return 403 instead of 401 on non-admin role

This commit is contained in:
Charles Zhao 2022-06-07 17:22:34 +08:00
parent 0cb407c0dd
commit ee16eeb966
No known key found for this signature in database
GPG key ID: 4858774754C92DF2
4 changed files with 42 additions and 7 deletions

View file

@ -22,6 +22,19 @@ describe('koaAuth middleware', () => {
};
const unauthorizedError = new RequestError({ code: 'auth.unauthorized', status: 401 });
const jwtSubMissingError = new RequestError({ code: 'auth.jwt_sub_missing', status: 401 });
const authHeaderMissingError = new RequestError({
code: 'auth.authorization_header_missing',
status: 401,
});
const tokenNotSupportedError = new RequestError(
{
code: 'auth.authorization_token_type_not_supported',
status: 401,
},
{ supportedTypes: ['Bearer'] }
);
const forbiddenError = new RequestError({ code: 'auth.forbidden', status: 403 });
const next = jest.fn();
@ -67,7 +80,7 @@ describe('koaAuth middleware', () => {
});
it('expect to throw if authorization header is missing', async () => {
await expect(koaAuth()(ctx, next)).rejects.toMatchError(unauthorizedError);
await expect(koaAuth()(ctx, next)).rejects.toMatchError(authHeaderMissingError);
});
it('expect to throw if authorization header token type not recognized ', async () => {
@ -78,7 +91,9 @@ describe('koaAuth middleware', () => {
},
};
await expect(koaAuth()(ctx, next)).rejects.toMatchError(unauthorizedError);
console.log('????????????????', tokenNotSupportedError);
await expect(koaAuth()(ctx, next)).rejects.toMatchError(tokenNotSupportedError);
});
it('expect to throw if jwt sub is missing', async () => {
@ -92,7 +107,7 @@ describe('koaAuth middleware', () => {
},
};
await expect(koaAuth()(ctx, next)).rejects.toMatchError(unauthorizedError);
await expect(koaAuth()(ctx, next)).rejects.toMatchError(jwtSubMissingError);
});
it('expect to throw if jwt role_names is missing', async () => {
@ -106,7 +121,7 @@ describe('koaAuth middleware', () => {
},
};
await expect(koaAuth(UserRole.Admin)(ctx, next)).rejects.toMatchError(unauthorizedError);
await expect(koaAuth(UserRole.Admin)(ctx, next)).rejects.toMatchError(forbiddenError);
});
it('expect to throw if jwt role_names does not include admin', async () => {
@ -122,6 +137,21 @@ describe('koaAuth middleware', () => {
},
};
await expect(koaAuth(UserRole.Admin)(ctx, next)).rejects.toMatchError(unauthorizedError);
await expect(koaAuth(UserRole.Admin)(ctx, next)).rejects.toMatchError(forbiddenError);
});
it('expect to throw unauthorized error if unknown error occurs', async () => {
const mockJwtVerify = jwtVerify as jest.Mock;
mockJwtVerify.mockImplementationOnce(() => {
throw new Error('unknown error');
});
ctx.request = {
...ctx.request,
headers: {
authorization: 'Bearer access_token',
},
};
await expect(koaAuth()(ctx, next)).rejects.toMatchError(unauthorizedError);
});
});

View file

@ -70,12 +70,15 @@ export default function koaAuth<StateT, ContextT extends IRouterParamContext, Re
if (forRole) {
assertThat(
roleNames?.includes(forRole),
new RequestError({ code: 'auth.unauthorized', status: 401 })
new RequestError({ code: 'auth.forbidden', status: 403 })
);
}
ctx.auth = sub;
} catch {
} catch (error: unknown) {
if (error instanceof RequestError) {
throw error;
}
throw new RequestError({ code: 'auth.unauthorized', status: 401 });
}

View file

@ -571,6 +571,7 @@ const errors = {
authorization_header_missing: 'Authorization header is missing.',
authorization_token_type_not_supported: 'Authorization type is not supported.',
unauthorized: 'Unauthorized. Please check credentials and its scope.',
forbidden: 'Forbidden. Please check your user roles and permissions.',
jwt_sub_missing: 'Missing `sub` in JWT.',
},
guard: {

View file

@ -554,6 +554,7 @@ const errors = {
authorization_header_missing: 'Authorization 请求 header 遗漏。',
authorization_token_type_not_supported: '不支持的 authorization 类型。',
unauthorized: '未授权。请检查相关 credentials 和 scope。',
forbidden: '禁止访问。请检查用户权限。',
jwt_sub_missing: 'JWT 中找不到 `sub`。',
},
guard: {