【问题标题】:Django's Custom Authentication Middleware & Authentication BackendDjango 自定义身份验证中间件和身份验证后端
【发布时间】:2021-02-06 07:28:52
【问题描述】:

我正在编写一个自定义身份验证中间件,用于检查标头中“授权”键的传入请求,其中包含一个令牌。

我正在使用此令牌与第三方 (Microsoft Graph) 检查用户的有效性。 MS Graph 将响应如下对象

# 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.
        ...

【问题讨论】:

  • 您在中间件中缺少一些代码,例如所有这些 if 语句所属的方法定义。此外,新代码不应使用MiddlewareMixin,而应符合 1.10+ 中间件 API。最终,兼容性 mixin 将会消失(我相信 4.0,但不确定)。

标签: django django-authentication


【解决方案1】:

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

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/

编辑:

它和我对中间件做的事情一样吗?

不,不是。

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

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

【讨论】:

  • 这是为了处理响应。就我而言,我想处理请求。我已经用我的自定义中间件代码更新了这个问题。谢谢!
  • 感谢 Bytesmith!我会仔细看看的。我同意中间件与请求/响应有关。
猜你喜欢
  • 2018-02-24
  • 2020-04-01
  • 2022-12-10
  • 2015-11-12
  • 1970-01-01
  • 2016-11-07
  • 1970-01-01
  • 1970-01-01
  • 2018-09-26
相关资源
最近更新 更多