Python Decorator для проверки безопасности веб-службы GAE - PullRequest
0 голосов
/ 01 октября 2009

В этом посте Ник предложил декоратора:

Python / WebApp Google App Engine - тестирование для пользователя / проход в заголовках

Я пишу API, чтобы представить потенциально десятки методов в качестве веб-сервисов, поэтому декоратор звучит как отличная идея.

Я попытался начать кодирование на основе этого примера: http://groups.google.com/group/google-appengine/browse_thread/thread/ac51cc32196d62f8/aa6ccd47f217cb9a?lnk=gst&q=timeout#aa6ccd47f217cb9a

Мне нужно, чтобы он был совместим с Python 2.5 для запуска под Google App Engine (GAE).

Вот моя попытка. Пожалуйста, просто укажите путь, если я на правильном пути или нет. В настоящее время выдается ошибка «Неверный синтаксис» в этой строке: класс WSTest (webapp.RequestHandler):

Моя идея - передать массив ролей декоратору. Это единственные роли (из моей базы данных, которые должны иметь доступ к каждому веб-сервису).

def BasicAuthentication(roles=[]):
  def _decorator(func):
    def _wrapper(*args, **kwds): 
        logging.info("\n\n BasicAuthentication:START:__call__ \n\n") 
        auth = None 
        if 'Authorization' in self.request.headers: 
           auth = self.request.headers['Authorization']
        if not auth:
           self.response.headers['WWW-Authenticate'] = 'Basic realm="MYREALM"'
           self.response.set_status(401)
           self.response.out.write("Authorization required")
           logging.info ("\n\n  Authorization required \n\n") 
           return 

        (username, password) = base64.b64decode(auth.split(' ')[1]).split(':')
        logging.info ("\n\n username = " + username + "  password=" + password + "\n\n")         

        isValidUserPass = False 
        usersSimulatedRole = "Admin" 
        #check against database here...  
        if user == "test12" and password == "test34":
           isValidUserPass = True  
        isValidRole = False 
        if usersSimulatedRole in roles:
           isValidRole = True 
        #next check that user has one of the roles 
        #  TODO 

        if not isValidUserPass:
           self.response.set_status(403)
           self.response.out.write("Forbidden: Userid/password combination failed")

        logging.info("\n\n BasicAuthentication:END:__call__ \n\n") 
        return func(*args, **kwds) 
    return _wrapper
  return _decorator 


@BasicAuthentication(["Admin","Worker"])   #list of roles that can run this function 
class WSTest(webapp.RequestHandler):
  def get(self):
     logging.info("\n\n\n WSTest \n\n") 
     ...etc...

Спасибо, Нил Уолтерс

Ответы [ 2 ]

2 голосов
/ 01 октября 2009

Вам нужно написать декоратор метода, а не декоратор класса: как указывает теория утраты, декораторы классов не существуют в Python 2.5, и они не будут работать очень хорошо в любом случае, потому что класс RequestHandler не инициализируется с данными запроса до после . Декоратор метода также дает вам больше контроля - например, вы можете разрешить GET-запросы без проверки подлинности, но при этом все же требовать аутентификации для POST-запросов.

Кроме того, ваш декоратор выглядит хорошо - просто примените его к соответствующим методам. Единственное изменение, которое я бы действительно предложил, это заменить вызовы .set_status () вызовами .error () и удалить вызовы response.write; это позволяет вам переопределить .error () в классе RequestHandler, чтобы вывести красивую страницу ошибки для каждого возможного кода состояния.

2 голосов
/ 01 октября 2009

Классовые декораторы были добавлены в Python 2.6 .

Вам придется вручную обернуть класс или придумать другое решение для работы под 2.5. Как насчет написания декоратора для метода get вместо

...