You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django应用使用ms_identity_web.login_required返回401而非跳转登录页

Django + ms_identity_web 认证跳转问题

我用Django开发的应用,通过ms_identity_web对接Azure AD做认证,认证功能正常,但未登录时直接访问带@ms_identity_web.login_required装饰器的受保护页面,会返回401错误,不像Django原生@login_required那样自动跳转到登录页。

找不到相关文档,尝试写自定义中间件,但卡在无法判断请求路径对应的视图是否带有该装饰器。优先想找库内置的解决方案,也接受其他可行方案。

配置代码(settings.py)

from ms_identity_web.configuration import AADConfig
from ms_identity_web import IdentityWebPython

AAD_CONFIG = AADConfig.parse_json(file_path='aad.config.json')
MS_IDENTITY_WEB = IdentityWebPython(AAD_CONFIG)
ERROR_TEMPLATE = 'auth/{}.html'

视图代码

ms_identity_web = settings.MS_IDENTITY_WEB

@ms_identity_web.login_required
def view_data(request):
    context = {
        'data': 'test'
    }
    return render(request, 'data_management/view_data.html', context)

自定义中间件代码

from django.shortcuts import redirect
from django.urls import reverse
from django.conf import settings
from django.urls import resolve

ms_identity_web = settings.MS_IDENTITY_WEB

class MsLoginUrlMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        if resolve(request.path).url_name == 'view_data': # 这里应该判断视图是否带装饰器
            print('view data url found')

            if request.identity_context_data.authenticated is False:
                print('step 1:login required:')
                
                if request.path.startswith('/auth/sign_in') is False:
                    print('step 2: auth required, sending to login page..')
                    return redirect('/auth/sign_in')
                else:
                    print('user should log in now..')
                    return self.get_response(request)
        
        return self.get_response(request)

解决方案

方案1:自定义装饰器替换原装饰器(推荐)

ms_identity_web的login_required默认返回401,我们可以自己包装一层,实现跳转逻辑:

from django.shortcuts import redirect

def aad_login_required(view_func):
    def wrapper(request, *args, **kwargs):
        if not request.identity_context_data.authenticated:
            # 跳转到库自带的登录路径
            return redirect('/auth/sign_in')
        return view_func(request, *args, **kwargs)
    return wrapper

之后把视图里的@ms_identity_web.login_required替换成@aad_login_required即可。

方案2:批量配置受保护路径的中间件

在settings里定义需要保护的路径列表:

# settings.py
PROTECTED_PATHS = ['/view-data/', '/admin/'] # 替换成你的实际路径

然后修改中间件,批量检查路径:

class MsLoginUrlMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        for path in settings.PROTECTED_PATHS:
            if request.path.startswith(path):
                if not request.identity_context_data.authenticated:
                    if not request.path.startswith('/auth/sign_in'):
                        return redirect('/auth/sign_in')
                break
        return self.get_response(request)

方案3:利用错误模板自动跳转

你已经配置了ERROR_TEMPLATE = 'auth/{}.html',直接创建auth/401.html模板,添加自动跳转逻辑:

<!-- auth/401.html -->
<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="refresh" content="0; url=/auth/sign_in">
</head>
<body>
    未登录,正在跳转至登录页面...
</body>
</html>

这样返回401时会渲染该模板,自动跳转到登录页。

内容的提问来源于stack exchange,提问作者jdenboer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 01:02:46