在通过从repoze.who中删除所有base_config.sa_auth...和base_config.auth_backend来禁用config/app_.cfg.py的默认配置之后,应该可以在config/middleware.py中将repoze.who配置为中间件。
所以我创建了一个像这样的文件config/auth.py:
from logging import getLogger
from repoze.who.middleware import PluggableAuthenticationMiddleware
from repoze.who.classifiers import default_challenge_decider, default_request_classifier
from repoze.who.plugins.basicauth import BasicAuthPlugin
from repoze.who.plugins.htpasswd import HTPasswdPlugin, plain_check
def add_auth(app):
htpasswd = HTPasswdPlugin('/.../htpasswd', plain_check)
authenticators = [('htpasswd', htpasswd)]
base_auth = BasicAuthPlugin('Inventory DB')
challengers = [('base_auth', base_auth)]
identifiers = [('base_auth', base_auth)]
mdproviders = []
log_stream = getLogger('auth')
app_with_mw = PluggableAuthenticationMiddleware(
app,
identifiers,
authenticators,
challengers,
mdproviders,
default_request_classifier,
default_challenge_decider,
log_stream,
)
return app_with_mw其中plain_text密码仅用于测试。然后,在config/middleware.py中,导入该函数并将其应用于app,作为make_app函数的最后一步。
from invdb.config.app_cfg import base_config
from invdb.config.environment import load_environment
from auth import add_auth
__all__ = ['make_app']
make_base_app = base_config.setup_tg_wsgi_app(load_environment)
def make_app(global_conf, full_stack=True, **app_conf):
app = make_base_app(global_conf, full_stack=True, **app_conf)
app = add_auth(app)
return app现在的问题是,身份验证不起作用。不需要任何身份验证的控制器不会挑战。带有allow_only = tg.predicate.not_anonymous的控制器将挑战http-身份验证。但是,即使plain_check返回True,登录立即被遗忘,挑战再次显示。tg.request.identity留下None。
我做错了什么?
发布于 2014-05-26 20:17:24
有一个简单得多的解决方案,就是用自定义中间件替换整个身份验证堆栈。正如认证文件所提到的,您可以从app_cfg.py本身配置身份验证堆栈。
例如,如果要强制使用基本的auth用法,只需设置challengers、identifiers和authenticators,然后返回数据以使用authmetadata填充tg.request.identity。
下面是一个用于basic的示例app_cfg (请记住删除任何其他basic_config.sa_auth条目,否则可能会导致意外参数崩溃):
# Name our custom auth backend, if this is None TG will
# disable the whole authentication stack.
base_config.auth_backend = 'htpasswd'
from tg.configuration.auth import TGAuthMetadata
#This tells to TurboGears how to retrieve the data for your user
class ApplicationAuthMetadata(TGAuthMetadata):
def __init__(self, sa_auth):
self.sa_auth = sa_auth
def get_user(self, identity, userid):
# As we use htpasswd for authentication
# we cannot lookup the user in a database,
# so just return a fake user object
from tg.util import Bunch
return Bunch(display_name=userid, user_name=userid)
def get_groups(self, identity, userid):
# If the user is manager we give him the
# managers group, otherwise no groups
if userid == 'manager':
return ['managers']
else:
return []
def get_permissions(self, identity, userid):
return []
base_config.sa_auth.authmetadata = ApplicationAuthMetadata(base_config.sa_auth)
from repoze.who.plugins.basicauth import BasicAuthPlugin
from repoze.who.plugins.htpasswd import HTPasswdPlugin, plain_check
# Use htpasswd for checking user credentials, remember to write the password in clear
# text as we are using the plain_check function to check them.
base_config.sa_auth.authenticators = [('htpasswd', HTPasswdPlugin('./passwd_file', plain_check))]
# Use BasicAuth plugin to ask user for credentials, this will replace
# the whole login form and cookie based authentication
base_auth = BasicAuthPlugin('MyTGApp')
base_config.sa_auth.challengers = [('basicauth', base_auth)]
base_config.sa_auth.identifiers = [('basicauth', base_auth)]
# Disable the login form, it won't work anyway as the credentials
# for basic auth must be provided through the browser itself
base_config.sa_auth.form_identifies = False发布于 2014-05-26 20:36:20
amol的答案很可能是你应该怎么做。无论如何,这是我在此找到的解决方案:不要使用内置的predicate.not_anonymous。这似乎依赖于未配置的repoze.what或AuthMetaData的部分。所以我发明了我自己的谓词:
class identified_user(predicates.Predicate):
def evaluate(self, environ, credentials):
if environ.get('repoze.who.identity') is None:
self.unmet()https://stackoverflow.com/questions/23872416
复制相似问题