Django 自定义身份验证中间件和身份验证后端

Django's Custom Authentication Middleware & Authentication Backend

我正在编写自定义身份验证中间件,用于检查 header 中包含令牌的“授权”密钥的传入请求。

我正在使用此令牌通过 third-party (Microsoft Graph) 检查用户的有效性。 MS Graph 将以 object 响应,如下所示

# the response object

{
    '@odata.context': 'https://graph.microsoft.com/v1.0/$metadata#users/$entity',
    'businessPhones': ['xxx'],
    'displayName': 'xxx',
    'givenName': 'xxx',
    'id': 'xxx',
    'jobTitle': None,
    'mail': 'xxx',
    'mobilePhone': None,
    'officeLocation': None,
    'preferredLanguage': 'xxx',
    'surname': 'xxx',
    'userPrincipalName': 'xxx'
}

编辑:在此处添加自定义中间件代码:

class AuthenticationMiddleware(MiddlewareMixin):
    if not request.user.is_authenticated:
        if "Authorization" in request.headers:
            # Make a request to MS Graph with the given token
            # to get user details and append to request
            token = request.headers["Authorization"]
        elif "accessToken" in request.GET:
            token = request.GET["accessToken"]
        else:
            token = None

        if token:
            url = "https://graph.microsoft.com/v1.0/me/"
            payload = {}
            headers = {"Authorization": "Bearer {}".format(token)}
            response = requests.request("GET", url, headers=headers, data=payload)
            if response.ok:
                request.custom_user = response.json()
            else:
                request.custom_user = AnonymousUser
        else:
            request.custom_user = AnonymousUser

现在我想将其设计为像 Django 的默认身份验证后端一样工作,具有适当的组和权限。我如何处理 LazyObject 才能检查用户的组成员资格和权限?

更新

看起来还有一个像这样工作的自定义后端身份验证。

是不是和我用中间件做的一样?

from django.contrib.auth.backends import BaseBackend

class MyBackend(BaseBackend):
    def authenticate(self, request, token=None):
        # Check the token and return a user.
        ...

你应该像下面这样自定义一个中间件,并在设置中将其添加到中间件

class SimpleMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        # One-time configuration and initialization.

    def __call__(self, request):
        # Code to be executed for each request before
        # the view (and later middleware) are called.

        response = self.get_response(request)

        # todo: do something you want in response 
        return response

另请参阅:https://docs.djangoproject.com/en/3.1/topics/http/middleware/

编辑:

Is it doing the same thing as I'm doing with the middleware?

不,不是。

最不同的是 后端用于连接数据库,中间件用于处理请求。您可以在 django.middleware 包中找到更多示例代码。

如果您想自定义如何将信息保存到数据库,例如:自定义 authenticate 方法,您应该为该工作自定义一个后端。否则你可以定制一个中间件来处理所有的请求。因为中间件很容易定制。