Конечные точки API-шлюза, которые мы используем, должны быть ограничены с помощью разрешений для определенной аудитории.
Идея состоит в том, чтобы использовать lambda-авторизатор для получения разрешений от внешней службы, а затем создать политику, чтобы разрешить илизапретить доступ к конечной точке.
Для сопоставления разрешений с конечной точкой API конечная точка должна будет предоставить разрешения, необходимые для авторизатора.
Теперь у меня вопрос, как я могу обогатитьданные конечной точки с собственными необходимыми разрешениями и их использование в лямбда-выражении авторизатора (возможно, через событие) для дальнейшей проверки.
Пример:
- Пользователь1 перенаправляется на первую конечную точку GET / petstore / pets (для этой конечной точки требуется разрешение -> Просмотр: Pets )
- Lambda авторизатор запрашивает разрешения пользователя у внешней службы
- Служба возвращает: [ Вид: Домашние животные , Вид: Somethingelse и т. Д.]
- Лямбда-мат авторизатораches пользовательские разрешения для требуемого разрешения конечной точки и создает политику разрешений для совпадения
- User2 делает то же самое, но не имеет разрешения для просмотра домашних животных, нет совпадений -> Запретить
Вот мой код для лямбды:
import {Callback, Context} from 'aws-lambda';
import {Authorizer} from './authorizer';
export class App {
constructor(private authorizer: Authorizer = new Authorizer()) {
}
public handleEvent(event, callback: Callback): Promise<void> {
return this.authorizer.checkAuthorization(event, callback)
.then((policy) => callback(null, policy))
.catch((error) => callback(error, null));
}
}
const app: App = new App();
module.exports.lambda_handler = async (event) => {
return await app.handleEvent(event);
};
Код для метода checkAuthorization:
export class Authorizer {
public resourceAuthorizer: ResourceAuthorizer = new ResourceAuthorizer();
public authenticationChecker: AuthenticationChecker = new AuthenticationChecker();
public checkAuthorization(event, callback): Promise<object> {
const endpointPermissions = event.endpointPermissions; // <== this is what I need, a custom field in the event which
// is provided from the api endpoint in some way
// in my example this whould contain a string or json
// with 'View:Pets' and 'View:Somethingelse'
return this.authenticationChecker.check(event)
.then((decodedJwt) => {
const principalId: string = decodedJwt.payload.sub;
return Promise.resolve(decodedJwt)
.then((jwt) => this.resourceAuthorizer.check(jwt, event.endpointPermissions))
.then((payload) => callback(null,
getAuthorizationPolicy(principalId, 'Allow', event.endpointPermissions, payload)))
.catch((payload) => callback(null,
getAuthorizationPolicy(principalId, 'Deny', event.endpointPermissions, payload)));
}).catch((error) => {
console.log(error);
callback('Unauthorized');
});
}
}
event.endpointPermissions в основном то, что я ищу,В зависимости от конечной точки API это должно быть заполнено необходимыми разрешениями для этой конечной точки.Затем resourceAuthorizer извлекает разрешения пользователей из внешней службы и сравнивает их с endpointPermissions, а затем создает политики «Разрешить» или «Запретить».
Итак, где я могу ввести endpointPermissions в моей конечной точке API, чтобы предоставить их авторизатору?