0

とをrepoze.whoすべて削除して のデフォルト設定を無効にすると、 repoze.who を のミドルウェアとして設定できるようになります。base_config.sa_auth...base_config.auth_backendconfig/app_.cfg.pyconfig/middleware.py

だから私はこのようなファイルを作成しました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

私は何を間違っていますか?

4

2 に答える 2

2

認証スタック全体をカスタム ミドルウェアに置き換える、はるかに簡単なソリューションがあります。認証ドキュメントで述べられているように、認証スタックを自分自身から構成できますapp_cfg.py

たとえば、基本的な認証の使用を強制したい場合は、 を設定してchallengersから、identifiersを使用しauthenticatorsてデータを返すだけです。tg.request.identityauthmetadata

基本認証のサンプル 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-26T20:17:24.583 に答える
0

amolによる答えは、おそらくあなたがそれをどのように行うべきかです。とにかく、これが私がその間に見つけた解決策です:組み込みを使用しないでくださいpredicate.not_anonymousrepoze.whatこれは、または構成されていない部分に依存してAuthMetaDataいるようです。だから私は自分の述語を発明しました:

class identified_user(predicates.Predicate):
    def evaluate(self, environ, credentials):
        if environ.get('repoze.who.identity') is None:
            self.unmet()
于 2014-05-26T20:36:20.177 に答える