下午好,专家们,
我正试图在我的web应用程序中实现SAML身份验证。
我试图在djangosaml2库中使用django-saml2-auth-ai,但两个库都进入了重定向循环。
django-saml2-auth-ai (2.1.6)
urls.py:
url(r'^saml2_auth/', include('django_saml2_auth.urls')),
url(r'^accounts/login/$', django_saml2_auth.views.signin, name='login'),
url(r'^accounts/logout/$', django_saml2_auth.views.signout, name='logout'),
配置:
我将django_saml2_auth添加到INSTALLED_APPS中。
SAML2_AUTH = {
'SAML_CLIENT_SETTINGS': { # Pysaml2 Saml client settings
'entityid': 'http://localhost:7000/saml2_auth/acs/',
'metadata': {
'local': [
os.path.join(BASE_DIR, 'management_app/azure-ad-metadata.xml'),
],
},
'service': {
'sp': {
'logout_requests_signed': True,
'idp': 'https://sts.windows.net/8d469bba-ae86-4fe1-a36d-fa9d26ec8ab6/'
}
}
},
'debug': 1,
'DEFAULT_NEXT_URL': '/dashboard',
'NEW_USER_PROFILE': {
'USER_GROUPS': [], # The default group name when a new user logs in
'ACTIVE_STATUS': True, # The default active status for new users
'STAFF_STATUS': False, # The staff status for new users
'SUPERUSER_STATUS': False, # The superuser status for new users
},
'ATTRIBUTES_MAP': { # Change Email/UserName/FirstName/LastName to corresponding SAML2 userprofile attributes.
'email': 'name',
'username': 'name',
'first_name': 'givenname',
'last_name': 'surname',
},
'ASSERTION_URL': 'http://localhost:7000',
}
Azure Ad的基本SAML配置
Identifier (Entity ID) : http://localhost:7000/saml2_auth/acs/
Reply URL (Assertion Consumer Service URL) : http://localhost:7000/saml2_auth/acs/
djangosaml2 (1.4.0)
urls.py:
url(r'saml2/', include('djangosaml2.urls')),
配置:
我将djangosaml2添加到INSTALLED_APPS中,将djangosaml2.middleware.SamlSessionMiddleware添加到中间件中。
SAML_SESSION_COOKIE_NAME = 'saml_session'
SESSION_COOKIE_SECURE = True
SAML_DJANGO_USER_MAIN_ATTRIBUTE = 'email'
SAML_ATTRIBUTE_MAPPING = {
'uid': ('username', ),
'mail': ('email', ),
'cn': ('first_name', ),
'sn': ('last_name', ),
}
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
'djangosaml2.backends.Saml2Backend',
)
LOGIN_URL = '/saml2/login/'
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
import saml2
SAML_DEFAULT_BINDING = saml2.BINDING_HTTP_POST
SAML_LOGOUT_REQUEST_PREFERRED_BINDING = saml2.BINDING_HTTP_POST
SAML_IGNORE_LOGOUT_ERRORS = True
SAML_CREATE_UNKNOWN_USER = True
SAML_USE_NAME_ID_AS_USERNAME = True
from os import path
import saml2.saml
SAML_CONFIG = {
# full path to the xmlsec1 binary program
'xmlsec_binary': '/usr/bin/xmlsec1',
# your entity id, usually your subdomain plus the url to the metadata view
'entityid': 'http://localhost:7000/saml2/acs/',
# directory with attribute mapping
'attribute_map_dir': path.join(BASE_DIR, 'management_app/attribute-maps'),
# Permits to have attributes not configured in attribute-mappings
# otherwise...without OID will be rejected
'allow_unknown_attributes': True,
# this block states what services we provide
'service': {
# we are just a lonely SP
'sp' : {
'name': 'SP',
'name_id_format': saml2.saml.NAMEID_FORMAT_TRANSIENT,
# For Okta add signed logout requests. Enable this:
# "logout_requests_signed": True,
'endpoints': {
# url and binding to the assetion consumer service view
# do not change the binding or service name
'assertion_consumer_service': [
('http://localhost:7000/saml2/acs/', saml2.BINDING_HTTP_POST),
('http://localhost:7000/saml2/acs/', saml2.BINDING_HTTP_REDIRECT),
],
# url and binding to the single logout service view
# do not change the binding or service name
'single_logout_service': [
# Disable next two lines for HTTP_REDIRECT for IDP's that only support HTTP_POST. Ex. Okta:
('http://localhost:7000/saml2/ls/', saml2.BINDING_HTTP_REDIRECT),
('http://localhost:7000/saml2/ls/post', saml2.BINDING_HTTP_POST),
],
},
'signing_algorithm': saml2.xmldsig.SIG_RSA_SHA256,
'digest_algorithm': saml2.xmldsig.DIGEST_SHA256,
# Mandates that the identity provider MUST authenticate the
# presenter directly rather than rely on a previous security context.
'force_authn': False,
# Enable AllowCreate in NameIDPolicy.
'name_id_format_allow_create': False,
# attributes that this project need to identify a user
'required_attributes': ['email'],
# attributes that may be useful to have but not required
'optional_attributes': ['surname'],
'want_response_signed': False,
'authn_requests_signed': False,
'logout_requests_signed': True,
# Indicates that Authentication Responses to this SP must
# be signed. If set to True, the SP will not consume
# any SAML Responses that are not signed.
'want_assertions_signed': True,
'only_use_keys_in_metadata': True,
# When set to true, the SP will consume unsolicited SAML
# Responses, i.e. SAML Responses for which it has not sent
# a respective SAML Authentication Request.
'allow_unsolicited': True,
# in this section the list of IdPs we talk to are defined
# This is not mandatory! All the IdP available in the metadata will be considered instead.
'idp': {
# we do not need a WAYF service since there is
# only an IdP defined here. This IdP should be
# present in our metadata
# the keys of this dictionary are entity ids
'https://localhost/simplesaml/saml2/idp/metadata.php': {
'single_sign_on_service': {
saml2.BINDING_HTTP_REDIRECT: 'https://localhost/simplesaml/saml2/idp/SSOService.php',
},
'single_logout_service': {
saml2.BINDING_HTTP_REDIRECT: 'https://localhost/simplesaml/saml2/idp/SingleLogoutService.php',
},
},
},
},
},
# where the remote metadata is stored, local, remote or mdq server.
# One metadatastore or many ...
'metadata': {
'local': [path.join(BASE_DIR, 'management_app/azure-ad-metadata.xml')],
'remote': [{"url": "https://login.microsoftonline.com/8d469bba-ae86-4fe1-a36d-fa9d26ec8ab6/federationmetadata/2007-06/federationmetadata.xml?appid=3bf6313c-fee7-4925-8c66-b94d7dc44bb3"},],
# 'mdq': [{"url": "https://ds.testunical.it",
# "cert": "certficates/others/ds.testunical.it.cert",
# }]
},
# set to 1 to output debugging information
'debug': 1,
# Signing
'key_file': path.join(BASE_DIR, 'management_app/azure_ad_sso_saml_signing_private.key'), # private part
'cert_file': path.join(BASE_DIR, 'management_app/azure_ad_sso_saml_signing_public.cert'), # public part
# Encryption
'encryption_keypairs': [{
'key_file': path.join(BASE_DIR, 'management_app/azure_ad_sso_saml_signing_private.key'), # private part
'cert_file': path.join(BASE_DIR, 'management_app/azure_ad_sso_saml_signing_public.cert'), # public part
}],
# own metadata settings
'contact_person': [
{'given_name': 'Lorenzo',
'sur_name': 'Gil',
'company': 'Yaco Sistemas',
'email_address': 'lgs@yaco.es',
'contact_type': 'technical'},
{'given_name': 'Angel',
'sur_name': 'Fernandez',
'company': 'Yaco Sistemas',
'email_address': 'angel@yaco.es',
'contact_type': 'administrative'},
],
# you can set multilanguage information here
'organization': {
'name': [('Yaco Sistemas', 'es'), ('Yaco Systems', 'en')],
'display_name': [('Yaco', 'es'), ('Yaco', 'en')],
'url': [('http://www.yaco.es', 'es'), ('http://www.yaco.com', 'en')],
},
}
Azure Ad的基本SAML配置
Identifier (Entity ID) : http://localhost:7000/saml2/acs/
Reply URL (Assertion Consumer Service URL) : http://localhost:7000/saml2/acs/
我认为我可以使用这两个库对Azure AD进行身份验证,但是当令牌被检索到django-saml2-auth-ai或djangosaml2时,它就进入了一个重定向循环。我查看了类似问题发生的论坛,但不幸的是,它们的解决方案对我无效。
你能告诉我出什么事了吗?
谢谢!
+++++++++++更新1 +++++++++++++++
问题似乎是,我使用Azure AD不发送的自定义权限,Django拒绝它并将其重定向到登录。但是cookie在那里,所以相同的用户将自动登录,Django拒绝,等等。
如果用户没有权限,请提供任何帮助,如何显示Azure AD登录页面?谢谢!
发布于 2022-09-13 21:54:19
问题是我使用自定义权限,但是登录(在Azure中)的用户没有->,请参阅更新1部分
如果用户没有权限,我更改了代码以引发异常
@permission_required('XXX', raise_exception=True)
所以这个403错误可以用
handler403 = 'XXX.custom_403'
https://stackoverflow.com/questions/73082683
复制相似问题