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

时间:2020-10-23 08:25:12

标签: django django-authentication

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

我正在使用此令牌与第三方(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.
        ...

1 个答案:

答案 0 :(得分:0)

您应自定义如下所示的中间件,并将其添加到设置中的中间件

ocsp.catcert.cat

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

编辑:

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

不,不是。

最大的不同是 后端用于与数据库连接,中间件旨在处理请求。您可以在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 包中找到更多示例代码。

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