简体   繁体   English

如何在Twisted-Klein服务器上为特定的API端点禁用HTTP Basic Auth

[英]How to disable HTTP Basic Auth for specific API endpoints on Twisted-Klein server

I have simple Twisted-Klein server, with HTTP Basic Auth enabled globally: 我有一个简单的Twisted-Klein服务器,全局启用了HTTP基本身份验证:

from klein import Klein
import attr
from zope.interface import implementer
from twisted.cred.portal import IRealm
from twisted.internet.defer import succeed
from twisted.cred.portal import Portal
from twisted.cred.checkers import FilePasswordDB
from twisted.web.resource import IResource
from twisted.web.guard import HTTPAuthSessionWrapper, BasicCredentialFactory
from werkzeug.datastructures import MultiDict
from bson import json_util
import json


app = Klein()


# health check
@app.route('/health', methods=['GET'])
def health_check(request):
    return ''


# dataset query API
@app.route('/query/<path:expression>', methods=['GET'])
def query(request, expression):
    response = evaluate_expression(expression)
    return response


@implementer(IRealm)
@attr.s
class HTTPAuthRealm(object):
    resource = attr.ib()

    def requestAvatar(self, avatarId, mind, *interfaces):
        return succeed((IResource, self.resource, lambda: None))


def resource():
    realm = HTTPAuthRealm(resource=app.resource())
    portal = Portal(realm, [FilePasswordDB('./configs/server-auth.db')])
    credential_factory = BasicCredentialFactory('Authentication required')
    return HTTPAuthSessionWrapper(portal, [credential_factory])

I want to disable auth for only specific API endpoints, for example, in this case for /health API endpoint. 我只想对特定的API端点禁用身份验证,例如,在这种情况下,对/health API端点禁用身份验证。 I've read the docs, but just cant wrap my mind around it. 我已经阅读了文档,但是无法将其包裹住。

One way is to only wrap the part of the hierarchy that you want authentication for: 一种方法是只包装要验证的层次结构部分:

from twisted.web.resource import Resource

class Health(Resource):
    # ...

def resource():
    realm = HTTPAuthRealm(resource=app.resource())
    portal = Portal(realm, [FilePasswordDB('./configs/server-auth.db')])
    credential_factory = BasicCredentialFactory('Authentication required')
    guarded = HTTPAuthSessionWrapper(portal, [credential_factory])

    root = Resource()
    root.putChild(b"health", Health())
    root.putChild(b"this-stuff-requires-auth", guarded)

    return root

The normal resource traversal logic used for dispatching requests will start at root . 用于调度请求的常规资源遍历逻辑将从root开始。 If the request is for /health (or any child) then it goes to root 's health child - which is the Health instance created in this example. 如果请求是针对/health (或任何子项)的,那么它将转到roothealth子项-这是在此示例中创建的Health实例。 Note how the HTTPAuthSessionWrapper doesn't get involved there. 请注意, HTTPAuthSessionWrapper如何不参与其中。 If the request is for /this-stuff-requires-auth (or any child) then traversal does go through the auth wrapper and so authentication is required. 如果请求是针对/this-stuff-requires-auth (或任何子项)的,则遍历确实会通过auth包装器,因此需要进行身份验证。

Another approach is to vary your avatar based on the credentials. 另一种方法是根据凭据更改您的头像。 In this scheme, you actually still authenticate everyone but you authorize anonymous users to access some of the hierarchy. 在此方案中,您实际上仍对每个人进行身份验证,但您授权匿名用户访问某些层次结构。

from twisted.cred.checkers import ANONYMOUS

@implementer(IRealm)
@attr.s
class HTTPAuthRealm(object):
    def requestAvatar(self, avatarId, mind, *interfaces):
        avatar = Resource()
        avatar.putChild(b"health", Health())
        if avatarId is not ANONYMOUS:
            avatar.putChild(b"this-stuff-requires-auth", SecretResource())
        return succeed((IResource, avatar, lambda: None))

You'll also need to configure your portal with a credentials checker for anonymous credentials: 您还需要使用用于匿名凭证的凭证检查器来配置门户:

from twisted.cred.checkers import AllowAnonymousAccess

portal = Portal(
    realm, [
        FilePasswordDB('./configs/server-auth.db'),
        AllowAnonymousAccess(),
    ],
)

In this approach, HTTPAuthSessionWrapper is again your root resource. 在这种方法中, HTTPAuthSessionWrapper再次是您的根资源。

Anonymous requests are associated with the ANONYMOUS avatar identifier and HTTPAuthRealm gives back an IResource which only knows about the resources that should be available to anonymous users. 匿名请求与ANONYMOUS头像标识符相关联, HTTPAuthRealm返回一个IResource ,该资源仅知道匿名用户应可使用的资源。

Requests with valid user credentials are associated with a different avatar identifier (usually their username) and HTTPAuthRealm gives back an IResource with more children attached to it, granting more access. 具有有效用户凭据的请求与另一个头像标识符(通常是其用户名)相关联, HTTPAuthRealm会返回一个IResource ,该IResource具有附加的子级,从而授予更多访问权限。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM