我们正在尝试在 Google App Engine 中设置一个通过 SAML 连接到我们的 idP Okta 的 Web 应用程序 (django)。由于二进制要求,它必须作为自定义灵活应用程序完成,这基本上是一个容器部署。使用 gunicorn 在本地运行它(包括 SSL 配置)可以完美运行,但将其部署到 Google 时,效果并不好。
问题是 idP 到 sP 重定向失败,
Traceback:
File "/env/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
34. response = get_response(request)
File "/env/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
115. response = self.process_exception_by_middleware(e, request)
File "/env/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
113. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/env/lib/python3.6/site-packages/django/views/decorators/csrf.py" in wrapped_view
54. return view_func(*args, **kwargs)
File "/env/lib/python3.6/site-packages/django_saml2_auth/views.py" in acs
159. resp, entity.BINDING_HTTP_POST)
File "/env/lib/python3.6/site-packages/saml2/client_base.py" in parse_authn_request_response
714. binding, **kwargs)
File "/env/lib/python3.6/site-packages/saml2/entity.py" in _parse_response
1213. response.require_signature = require_signature
Exception Type: AttributeError at /sso/acs/
Exception Value: 'NoneType' object has no attribute 'require_signature'
目前的理论是,应用程序前面的 Nginx 代理以某种方式干扰了 POST 请求并破坏了 SAML 断言,但尚未找到此类设置或其文档。
一些新想法将不胜感激。
答案1
问题很简单:反向代理配置更改了 HTTP 请求(HTTPS 方案到 HTTP),这使得 Okta 插件(https://github.com/fangli/django-saml2-auth) 因模糊错误而失败。将 ASSERTION_URL 条目添加到 settings.py Django 文件中的 SAML2_AUTH 字典中即可解决问题。
答案2
如上所述,将 ASSERTION_URL 条目添加到 settings.py Django 文件中的 SAML2_AUTH 字典中将解决该Exception Value: 'NoneType' object has no attribute 'require_signature'
错误。
我想添加一些帮助我解决问题的细节。 就我而言,使用与 Okta 集成的 AWS Fargate 运行的 dockerized django,配置如下所示:
'ASSERTION_URL' : f"https://{ENV_VAR('YOUR_APP_URL')}" if "YOUR_APP_URL" in os.environ else 'http://127.0.0.1:8000',
使用条件让它在本地主机上运行以进行测试。另外,请注意前面的https
协议,以便清楚地了解我们试图解决的问题。
如果缺少此设置,除了上面提到的错误之外,日志输出中的另一个错误可能更有助于理解为什么'ASSERTION_URL'
需要该配置:
"https://your-domain/saml2_auth/acs/ not in ['http://your-domain/saml2_auth/acs/']"
当然,读完这个主题后,我又读了https://github.com/fangli/django-saml2-auth/其中写道:
“默认情况下,django-saml2-auth 将根据实际 HTTP 请求的主机和方案验证 SAML 响应的服务提供商地址。如果设置了此值,它将根据 ASSERTION_URL 进行验证 - 非常适合在反向代理后面运行的 django。”