Как обрабатывать аутентификацию и авторизацию с помощью?
Я разрабатываю систему, которая использует бережливость. Я хотел бы, чтобы личность клиента проверялась, а операции - ACLed. Предоставляет ли Thrift какую-либо поддержку?
3 ответа
Не напрямую. Единственный способ сделать это - иметь метод аутентификации, который создает (временный) ключ на сервере, а затем изменить все ваши методы так, чтобы первым аргументом был этот ключ, и все они дополнительно вызывают ошибку, не связанную с аутентификацией. Например:
exception NotAuthorisedException {
1: string errorMessage,
}
exception AuthTimeoutException {
1: string errorMessage,
}
service MyAuthService {
string authenticate( 1:string user, 2:string pass )
throws ( 1:NotAuthorisedException e ),
string mymethod( 1:string authstring, 2:string otherargs, ... )
throws ( 1:AuthTimeoutException e, ... ),
}
Мы используем этот метод и сохраняем наши ключи в защищенном экземпляре memcached с 30-минутным тайм-аутом для ключей, чтобы все было "быстро". Клиенты, которые получают AuthTimeoutException
ожидается повторная авторизация и повторная попытка, и у нас есть некоторые правила брандмауэра, чтобы остановить атаки методом перебора.
Такие задачи, как авторизация и разрешения, не рассматриваются как часть Thrift, главным образом потому, что эти вещи (как правило) больше связаны с логикой приложения, чем с общей концепцией RPC/ сериализации. Единственное, что Thrift поддерживает прямо из коробки, это TSASLTransport
, Я не могу много сказать об этом сам, просто потому, что я никогда не чувствовал необходимости использовать его.
Другим вариантом может быть использование THeaderTransport
который, к сожалению, на момент написания реализован только с C++. Следовательно, если вы планируете использовать его на каком-либо другом языке, вам, возможно, придется инвестировать некоторую дополнительную работу. Излишне говорить, что мы принимаем вклады...
Немного поздно (наверное, очень поздно), но я изменил исходный код Thrift для этого пару лет назад.
Просто отправил тикет с патчем на https://issues.apache.org/jira/browse/THRIFT-4221 только для этого.
Посмотрите на это. По сути, предложение заключается в добавлении хука "BeforeAction", который делает именно это.
Пример сгенерированного Голанга diff
+ // Called before any other action is called
+ BeforeAction(serviceName string, actionName string, args map[string]interface{}) (err error)
+ // Called if an action returned an error
+ ProcessError(err error) error
}
type MyServiceClient struct {
@@ -391,7 +395,12 @@ func (p *myServiceProcessorMyMethod) Process(seqId int32, iprot, oprot thrift.TP
result := MyServiceMyMethodResult{}
var retval string
var err2 error
- if retval, err2 = p.handler.MyMethod(args.AuthString, args.OtherArgs_); err2 != nil {
+ err2 = p.handler.BeforeAction("MyService", "MyMethod", map[string]interface{}{"AuthString": args.AuthString, "OtherArgs_": args.OtherArgs_})
+ if err2 == nil {
+ retval, err2 = p.handler.MyMethod(args.AuthString, args.OtherArgs_)
+ }
+ if err2 != nil {
+ err2 = p.handler.ProcessError(err2)