megalus / django-microsoft-sso

Easily add Microsoft 365 Authentication to Django Admin
https://megalus.github.io/django-microsoft-sso/
MIT License
9 stars 6 forks source link

Django Microsoft SSO (Azure Authentication) Fails: Callback URL Not Reachable or Redirects to Admin Login Page in a Loop #13

Open vinodhkumartandrothu opened 1 month ago

vinodhkumartandrothu commented 1 month ago

Django Microsoft SSO not working and site cannot be reached or redirected back to the admin login page (looping without successful login) at

http://localhost:8000/microsoft_sso/callback/?code=0.AW8Bdq0dh0K3-km8RSyHvV9bYkME2G7dNWhAp9xtpk9VIMlvAQA.AgABBAIAAAApTwJmzXqdR4BN2miheQMYAwDs_wUA9P_cCeWTUEuL_3GAxw2pLR3yopUhdJKxKur6SFer5Mbi4Uf8Z0HTxttwsJv8jeqy1zIe0xows6UVIgb_w1wOsjzuhiyUWHTQt-dbOE9ZEhZ5rf_spYcEMRyOmqxOZP3snDSqnfutGIae3xrHo9tRGIbigbCsvvcjWvHhg1ATPG5n4SAcpHWf65B7KraWrI-1L0ngrL9kWvh8f38I8EM0RKvGYHqS-KWR86pPKWXdcXFKdlkh4FRLrdS_VURknXDjaKh5q_kqXoCDnhfAnvteiyM5_lkdYKLAh3orD8rn1PIMv4Qf4B52MPTl33hv7-jVoq_93uf8l8HDhRrECvjU7LxjQZhPUPNEa50kZ56JasVp1Eg2oWfYqFCsxQSB5iHePRwsENSu8NUTFWFhRuWrfNXkw2xEAiHOZx8EpA0djNmaawBfxS0o3xJhRnn5kzFAYxj1mCUO9tLS63GYKQbZa_nQ8LacADanknRjVwJnelMHuSBrT8N3PP-wSB7pcvJtZJnGz5AheNg5yvi1hj-F0iK3It5WfPGRcy8mBkSDDjXOtJJKJov_s-PBTIF7_kW46jhhntlV3BSgv1G_lukt4PH8bzgWv_A9AbMC43JLIxoiEDJBIsOMn3XKlfgjAyB2-pgnlFf5zsiHqj64as7-IgRwcAMn9QYYy52qQqkiJQSnJ_27jmd-ipVikvtffE4k6QLl23-4sdNMH3RdsyztfJLTVI4n3fmiRB6L5bzu_srvu0gTl2kbw_Ch-zuX8m-DzxWQ16885oAG1Lk7B0LGXeIrGk-Wby_XAXx9XBFz7J0SA1REe4Byw_ZYXzqv3HeIEqJw9w3wNV8dxBc_W1wzfz0FqRCgyoeWRkAOZ7V6_HpheiDK8VUcpbN56axOICRxccVTH-Swy3MNEmtB1xemk3XBgvVmVOD3DMSaVn4LH7o0d8tcmNCnQt2k6-KOX_-mMFjNddZ3Le2y-FJmYP-6QKAb2LR_GWZ_5XlA0Kfqa2Abp0Sh2PtNCQG7C7FllFrvj0McElogGd2AFGi4jpmAzVy2l03CBBOVJ7L76fwHOSjy15BhbalHitzopbaTF4MaTLvWImEHiqipZavk3E0tfoMh2cZjuQHP9eNescB69Di9LzQeOsJHMcBZaytnvW3mXCYSQrOYJXgPx6oXUIjiu3EogMqmMXgexEtRzNs0XY5D09pgRYSob86ohiZiy5KKc_FoABHDU1s_KNa_woBEVgeV5374DeqMREXYwyRNKBELEhgz2zKLeBfPT8-dLbsbFL7a3GrobEawd48GVxmu0r-uA1D0z3alqIWboymWnqgRyxMmmtYe65QqfeDYW0ZaCfEMpWp4XyXic-lIzJbL6hKefGfxC7e3h-Y&client_info=eyJ1aWQiOiIwMDAwMDAwMC0wMDAwLTAwMDAtOWQ4YS05MGQ2MWQ0NzM4ZGEiLCJ1dGlkIjoiOTE4ODA0MGQtNmM2Ny00YzViLWIxMTItMzZhMzA0YjY2ZGFkIn0&state=18109584-3108-4050-9fcf-4aea13f3d828&session_state=139d2609-f5f0-4a82-b96b-599f4f350aff#

Please see the logs below Logs:

Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (2 silenced).
September 17, 2024 - 06:39:07
Django version 5.1.1, using settings 'example_microsoft_app.settings'
Starting development server at http://localhost:8000/
Quit the server with CONTROL-C.

[17/Sep/2024 06:46:47] "GET /admin HTTP/1.1" 301 0
[17/Sep/2024 06:46:47] "GET /admin/ HTTP/1.1" 302 0
[17/Sep/2024 06:46:47] "GET /admin/login/?next=/admin/ HTTP/1.1" 200 6277
[17/Sep/2024 06:46:47] "GET /static/admin/css/dark_mode.css HTTP/1.1" 200 2804
[17/Sep/2024 06:46:47] "GET /static/admin/css/login.css HTTP/1.1" 200 951
[17/Sep/2024 06:46:47] "GET /static/admin/css/base.css HTTP/1.1" 200 22092
[17/Sep/2024 06:46:47] "GET /static/django_microsoft_sso/microsoft_button.css HTTP/1.1" 200 2283
[17/Sep/2024 06:46:47] "GET /static/django_google_sso/google_button.css HTTP/1.1" 200 1195
[17/Sep/2024 06:46:47] "GET /static/admin/css/nav_sidebar.css HTTP/1.1" 200 2810
[17/Sep/2024 06:46:47] "GET /static/admin/js/theme.js HTTP/1.1" 200 1653
[17/Sep/2024 06:46:47] "GET /static/admin/css/responsive.css HTTP/1.1" 200 17972
[17/Sep/2024 06:46:47] "GET /static/admin/js/nav_sidebar.js HTTP/1.1" 200 3063
2024-09-17 06:46:48.922 | DEBUG    | django_microsoft_sso.main:get_netloc:40 - Find Netloc using MICROSOFT_SSO_CALLBACK_DOMAIN
2024-09-17 06:46:48.923 | DEBUG    | django_microsoft_sso.main:get_redirect_uri:55 - Callback URI: http://localhost:8000/microsoft_sso/callback/
[17/Sep/2024 06:46:48] "GET /microsoft_sso/login/?next=/admin/ HTTP/1.1" 302 0
2024-09-17 06:47:07.436 | DEBUG    | backend:pre_create_callback:54 - Microsoft Graph API response: {'@odata.context': 'https://graph.microsoft.com/v1.0/$metadata#users/$entity', 'businessPhones': [], 'displayName': 'Vinodh K', 'givenName': 'Vinodh', 'jobTitle': None, 'mail': None, 'mobilePhone': None, 'officeLocation': None, 'preferredLanguage': 'en', 'surname': 'K', 'userPrincipalName': 'vinodhdlegend_gmail.com#EXT#@vinodhdlegendgmail.onmicrosoft.com', 'id': '269fdab1-f518-4b46-8a78-b575936258f2', 'email_verified': False}
2024-09-17 06:47:07.446 | DEBUG    | backend:pre_create_callback:71 - Creating new user with username: vinodhdlegend_gmail.com#EXT#_269fdab1f5184b468a78b575936258f2
2024-09-17 06:47:07.446 | DEBUG    | backend:pre_create_callback:73 - Creating user with username: vinodhdlegend_gmail.com#EXT#_269fdab1f5184b468a78b575936258f2
2024-09-17 06:47:07.611 | DEBUG    | backend:pre_create_callback:83 - Organization Info: {'@odata.context': 'https://graph.microsoft.com/v1.0/$metadata#organization', 'value': [{'id': '871dad76-b742-49fa-bc45-2c87bd5f5b62', 'deletedDateTime': None, 'businessPhones': [], 'city': None, 'country': None, 'countryLetterCode': 'US', 'createdDateTime': '2024-09-13T02:06:06Z', 'defaultUsageLocation': None, 'displayName': 'Default Directory', 'isMultipleDataLocationsForServicesEnabled': None, 'marketingNotificationEmails': [], 'onPremisesLastSyncDateTime': None, 'onPremisesSyncEnabled': None, 'partnerTenantType': None, 'postalCode': None, 'preferredLanguage': 'en', 'securityComplianceNotificationMails': [], 'securityComplianceNotificationPhones': [], 'state': None, 'street': None, 'technicalNotificationMails': ['vinodhdlegend@gmail.com'], 'tenantType': 'AAD', 'directorySizeQuota': {'used': 38, 'total': 50000}, 'privacyProfile': None, 'assignedPlans': [], 'onPremisesSyncStatus': [], 'provisionedPlans': [], 'verifiedDomains': [{'capabilities': 'Email, OfficeCommunicationsOnline', 'isDefault': True, 'isInitial': True, 'name': 'vinodhdlegendgmail.onmicrosoft.com', 'type': 'Managed'}]}]}
[17/Sep/2024 06:47:07] "GET /microsoft_sso/callback/?code=0.AW8Bdq0dh0K3-km8RSyHvV9bYkME2G7dNWhAp9xtpk9VIMlvAQA.AgABBAIAAAApTwJmzXqdR4BN2miheQMYAwDs_wUA9P_07xhJhktIq_iuApV9Bo_oyZkWCofvpakZVlhQsIomCumG_H0vr9zWfRjBZqrRqiWVzJCZxfYXFql5JY7t-wEirmjW6XntY6ZxC3ttUOfE5GD5Wph-GEJwsg_oonib4T953sxRs4IduUYy2eTjd-RvnAkI26a-CL16VdfZQCSLFCBK7klO92lsaHVhNSYlztcFHWXpdLvPlQ9Zr3Y1cyTf3GoVDdNwxcfy6TLwIUtKT7HodMYZ8UGK1eRhBDMKHAXegqp8IZSOzo5f5cFSbI_OJ-z4rcPabW2PxZS-MQqnXG5uMpkYDlDxpMhaUWedsFI0zpBqLqCTk2ZRt4LTHdWowwVpC7r9b1jDvTHcuRM_ugz8TTrb5byY_NaGF1wu3eE458EDpfNgJdSU1KbPVinTPjMQXaglqnS0kungGRUATTOTe4A3z8u4Pg3qDW_fheRE4yeiqdXincEKGoAKPEO3Q6h2TG06kaCbp4wzQuQLVQScCzpqLSvaGFe5hobRYcVwVZE5NvApP7EBYYhGPGQoL8j0YycV7G7OAsP7Svcgd5geMZpNTnDQx_UsXYJuKUbV-oqRIeDytwXGLNu87lijjUHRQfAmmqJZc30Q7jHXTy1XhDeEjA11iQ41cdQTaEFAo__mJWZuHHLVIH0edFcLVuK1s2XJY83qczFaDnfCmIDyqjF1ZwnsgfCw55kf7ygOz4bGhdTjrUlQryGnhoea3atHTY1qqoqN8TD8c9hguE6w_TdVINNhjn6NFqSXKLukKXELlNlJJWdYr68AmjP80hFgkESDQhQDF-A0gDrJ5NFwfCBCpUqjd9LhzHQfd-j_a9ulAu_-trJyWwHN0WdsGm0xjSpfsAOYJDzNFsRUDHCz7haYECYIREd40isKZ1BfWJ6WaRdmIKJIRnLTp7BDX5yihuUuC7O-CqVrYmwAIT4Qje3Yy0MMnHCI9EF3b9VAi4Ei7FQ0C2MYqhK6vws_O4e54sekGT9zEQYxnoVA-n_OBTqSLrpxfYr4prYaHhPRz8A1lfIpGPhhW08BT8kLzsj5_ON1nBPvLWrbz7QEgZYxpu3g6SGWWzeRx_XNquwyv4NLr-WE7IiQ-APXInFdDHanvAdmThpzmkBDHSgsnb1BJa0i85Nrhk5dMr3BibA0k7LQVGblWcbhKrkDW6LuZvwy4Bj8vilL7jnlxpSBbA4qG7Do8aXJpKMGNVB6cx_LWY54XiHhPNvIpHbM4Djgi3irMTUPx17dZhcxT_VYhAjdwYds-2ZcwAPZHmRRGSgH6Tk-yikQz7IaRZxyFxfbiOz_aeYWvhppHhpNMBr2hOoLkU9zwT215A8PU9ojJNGJUtdh_4PyH4eCXg0dWN1lyZAW&client_info=eyJ1aWQiOiIwMDAwMDAwMC0wMDAwLTAwMDAtOWQ4YS05MGQ2MWQ0NzM4ZGEiLCJ1dGlkIjoiOTE4ODA0MGQtNmM2Ny00YzViLWIxMTItMzZhMzA0YjY2ZGFkIn0&state=0c3359ce-820d-487b-8c62-cf0426442785&session_state=6ecc01fa-f0f4-4075-b58e-b19af3a9a42f HTTP/1.1" 302 0
[17/Sep/2024 06:47:07] "GET /admin/ HTTP/1.1" 302 0
[17/Sep/2024 06:47:07] "GET /admin/login/?next=/admin/ HTTP/1.1" 200 6426
[17/Sep/2024 06:47:07] "GET /static/admin/img/icon-yes.svg HTTP/1.1" 200 436

Server is running on http://localhost:8000/ and I will create an issue under original repo. Please see the logs above and please help me out.

I've set MICROSOFT_SSO_AUTO_CREATE_USERS = False in my settings.py file because I already have an existing user database, and I do not want the system to automatically create new users.

However, when I attempt to log in with these existing users, one of the following happens: I am redirected back to the admin login page (looping without successful login) or I receive a "Site cannot be reached" error.

path( "microsoft_sso/", include("django_microsoft_sso.urls", namespace="django_microsoft_sso"), ),

I have refered below links and did as per the guidelines.

https://pypi.org/project/django-microsoft-sso/ https://megalus.github.io/django-microsoft-sso/callback/

Refer the file which are required to review:

example_microsoft_app/settings.py https://github.com/vinodhkumartandrothu/django_microsoft_sso/blob/main/example_microsoft_app/urls.py https://github.com/vinodhkumartandrothu/django_microsoft_sso/blob/main/example_microsoft_app/.env

vinodhkumartandrothu commented 1 month ago

I have tried setting up the Django Microsoft SSO integration using both Poetry (please see above log) and a standard Python virtual environment. Despite following the necessary configuration steps in both environments, I am encountering the same issue: after successful authentication, the system redirects back to the admin login page instead of granting access. The following logs are from my current Python virtual environment setup, and the issue persists just as it did when using Poetry. (Added additional loggers.)

Log:

Converted retries value: 1 -> Retry(total=1, connect=None, read=None, redirect=None, status=None)
Initializing with Entra authority: https://login.microsoftonline.com/74xx
Starting new HTTPS connection (1): login.microsoftonline.com:443
https://login.microsoftonline.com:443 "GET /7xx7/v2.0/.well-known/openid-configuration HTTP/1.1" 200 1753
openid_config("https://login.microsoftonline.com/7xxx7/v2.0/.well-known/openid-configuration") = {'token_endpoint': 'https://login.microsoftonline.com/dre/oauh2/v2.0/', 'token_endpoint_auth_methods_supported': ['client_secret_post', 'private_key_jwt', 'client_secret_basic'], 'jwks_uri': 'https://login.microsoftonline.com/76556/discovery/v2.0/keys', 'response_modes_supported': ['query', 'fragment', 'form_post'], 'subject_types_supported': ['pairwise'], 'id_token_signing_alg_values_supported': ['RS256'], 'response_types_supported': ['code', 'id_token', 'code id_token', 'id_token token'], 'scopes_supported': ['openid', 'profile', 'email', 'offline_access'], 'issuer': 'https://login.microsoftonline.com/rtb7/v2.0', 'request_uri_parameter_supported': False, 'userinfo_endpoint': 'https://graph.microsoft.com/oidc/userinfo', 'authorization_endpoint': 'https://login.microsoftonline.com/tyuyu7/oauth2/v2.0/authorize', 'device_authorization_endpoint': 'https://login.microsoftonline.com/ttyutyu/oauth2/v2.0/devicecode', 'http_logout_supported': True, 'frontchannel_logout_supported': True, 'end_session_endpoint': 'https://login.microsoftonline.com/tyuf1b7/oauth2/v2.0/logout', 'claims_supported': ['sub', 'iss', 'cloud_instance_name', 'cloud_instance_host_name', 'cloud_graph_host_name', 'msgraph_host', 'aud', 'exp', 'iat', 'auth_time', 'acr', 'nonce', 'preferred_username', 'name', 'tid', 'ver', 'at_hash', 'c_hash', 'email'], 'kerberos_endpoint': 'https://login.microsoftonline.com/7xxxx/kerberos', 'tenant_region_scope': 'NA', 'cloud_instance_name': 'microsoftonline.com', 'cloud_graph_host_name': 'graph.windows.net', 'msgraph_host': 'graph.microsoft.com', rl': 'https://pas.windows.net'}
Broker enabled? None
2024-09-17 10:27:52.266 | DEBUG    | django_microsoft_sso.main:get_netloc:40 - Find Netloc using MICROSOFT_SSO_CALLBACK_DOMAIN
2024-09-17 10:27:52.266 | DEBUG    | django_microsoft_sso.main:get_redirect_uri:55 - Callback URI: http://localhost:8000/microsoft_sso/callback/
Page /microsoft_sso/login/ took 0.6013 seconds to load.
"GET /microsoft_sso/login/?next=null HTTP/1.1" 302 0
"GET /microsoft_sso/login/?next=null HTTP/1.1" 302 0
Converted retries value: 1 -> Retry(total=1, connect=None, read=None, redirect=None, status=None)
Initializing with Entra authority: https://login.microsoftonline.comxxxx
Starting new HTTPS connection (1): login.microsoftonline.com:443

'https://login.microsoftonline.comxxx7/oauth2/v2.0/authorize', 'device_authorization_endpoint': 'https://login.microsoftonline.com/7448cd93-a4af-42bc-a76b-890ed150f1b7/oauth2/v2.0/devicecode', 'http_logout_supported': True, 'frontchannel_logout_supported': True, 'end_session_endpoint': 'https://login.microsoftonline.com/thj0f1b7/oauth2/v2.0/logout', 'claims_supported': ['sub', 'iss', 'cloud_instance_name', 'cloud_instance_host_name', 'cloud_graph_host_name', 'msgraph_host', 'aud', 'exp', 'iat', 'auth_time', 'acr', 'nonce', 'preferred_username', 'name', 'tid', 'ver', 'at_hash', 'c_hash', 'email'], 'kerberos_endpoint': 'https://login.microsoftonline.com/7448cd93-a4af-42bc-a76b-890ed150f1b7/kerberos', 'tenant_region_scope': 'NA', 'cloud_instance_name': 'microsoftonline.com', 'cloud_graph_host_name': 'graph.windows.net', 'msgraph_host': 'graph.microsoft.com', 'rbac_url': 'https://pas.windows.net'}
Broker enabled? None
Generate or reuse correlation_id: 455cc
https://login.microsoftonline.com:443 "POST /oauth2/v2.0/token HTTP/1.1" 200 5025
event={
    "client_id": "5dg314--546456cf0403xxxx",
    "data": {
        "claims": null,

        "code": "jhgkj
        "code_verifier": "756868N",
        "redirect_uri": "http://localhost:8000/microsoft_sso/callback/",
        "scope": [
            "openid",
            "profile",
            "User.Read",
            "email",
            "offline_access"
        ]
    },
    "environment": "login.microsoftonline.com",
    "grant_type": "authorization_code",
    "params": null,
    "response": {
        "access_token": "********",
        "client_info": "
        "expires_in": 5178,
        "ext_expires_in": 5178,
        "id_token": "********",
        "refresh_token": "********",
        "scope": "email openid profile User.Read",
        "token_type": "Bearer"
    },
    "scope": [
        "email",
        "openid",
        "profile",
        "User.Read"
    ],
    "token_endpoint": "https://login.microsoftonline.com/3456/oauth2/v2.0/token"
}
load_ssl_context verify=True cert=None trust_env=True http2=False
load_verify_locations cafile='C:\\Users\\Vinodh\\My Repo\\Vetting App\\Lib\\site-packages\\certifi\\cacert.pem'
connect_tcp.started host='graph.microsoft.com' port=443 local_address=None timeout=5.0 socket_options=None
connect_tcp.complete return_value=<httpcore._backends.sync.SyncStream object at 0x000002F4731v50>
start_tls.started ssl_context=<ssl.SSLContext object at 0760> server_hostname='graph.microsoft.com' timeout=5.0
start_tls.complete return_value=<httpcore._backends.sync.SyncStream object at 0x000002F4v84C20>
send_request_headers.started request=<Request [b'GET']>
send_request_headers.complete
send_request_body.started request=<Request [b'GET']>
send_request_body.complete
receive_response_headers.started request=<Request [b'GET']>
receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'OK', [(b'Cache-Control', b'no-cache'), (b'Transfer-Encoding', b'chunked'), (b'Content-Type', b'application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8'), (b'Content-Encoding', b'gzip'), (b'Vary', b'Accept-Encoding'), (b'Strict-Transport-Security', b'max-age=31536000'), (b'request-id', 65'), (b'client-request-id',7), (b'x-ms-ags-diagnostic', b'{"ServerInfo":{"DataCenter":"South Central 
HTTP Request: GET https://graph.microsoft.com/v1.0/me "HTTP/1.1 200 OK"
receive_response_body.started request=<Request [b'GET']>
receive_response_body.complete
response_closed.started
response_closed.complete
close.started
close.complete
load_ssl_context verify=True cert=None trust_env=True http2=False
load_verify_locations cafile='C:\\Users\\Vinodh\\My Repo\\Vetting App\\Lib\\site-packages\\certifi\\cacert.pem'
connect_tcp.started host='graph.microsoft.com' port=443 local_address=None timeout=5.0 socket_options=None
connect_tcp.complete return_value=<httpcore._backends.sync.SyncStream object at 0x000002F47327D2E0>
start_tls.started ssl_context=<ssl.SSLContext object at 06575B5D0> server_hostname='graph.microsoft.com' timeout=5.0
start_tls.complete return_value=<httpcore._backends.sync.SyncStream object at 67F>
send_request_headers.started request=<Request [b'GET']>
send_request_headers.complete
send_request_body.started request=<Request [b'GET']>
send_request_body.complete
receive_response_headers.started request=<Request [b'GET']>
receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'OK', [(b'Cache-Control', b'no-cache'), (b'Transfer-Encoding', b'chunked'), (b'Content-Type', b'application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8'), (b'Content-Encoding', b'gzip'), (b'Vary', b'Accept-Encoding'), (b'Strict-Transport-Security', b'max-age=31536000'), (b'request-id', 7), (b'client-request-id',767'), (b'x-ms-ags-diagnostic', b'{"ServerInfo":{"DataCenter":"South Central 
HTTP Request: GET https://graph.microsoft.com/v1.0/userfgujjkila4dfff?$select=mailVerified "HTTP/1.1 200 OK"
receive_response_body.started request=<Request [b'GET']>
receive_response_body.complete
response_closed.started
response_closed.complete
close.started
close.complete
load_ssl_context verify=True cert=None trust_env=True http2=False
load_verify_locations cafile='C:\\Users\\VinodhTandrothu\\My Repo\\Vetting App\\Lib\\site-packages\\certifi\\cacert.pem'
connect_tcp.started host='graph.microsoft.com' port=443 local_address=None timeout=5.0 socket_options=None
connect_tcp.complete return_value=<httpcore._backends.sync.SyncStream object at 0x00fghj350>
start_tls.started ssl_context=<ssl.SSLContext object at 0x000002F47336F9D0> server_hostname='graph.microsoft.com' timeout=5.0
start_tls.complete return_value=<httpcore._backends.sync.SyncStream object at 0xfghj0>
send_request_headers.started request=<Request [b'GET']>
send_request_headers.complete
send_request_body.started request=<Request [b'GET']>
send_request_body.complete
receive_response_headers.started request=<Request [b'GET']>
receive_response_headers.complete return_value=(b'HTTP/1.1', 404, b'Not Found', [(b'Transfer-Encoding', b'chunked'), (b'Content-Type', b'application/json'), (b'Content-Encoding', b'gzip'), (b'Vary', b'Accept-Encoding'), (b'Strict-Transport-Security', b'max-age=31536000'), (b'request-id', b'64dfghj1'), (b'client-request-id', 66'), (b'x-ms-ags-diagnostic', b'{"ServerInfo":{"DataCenter":"South Central 
HTTP Request: GET https://graph.microsoft.com/v1.0/me/photo/$value "HTTP/1.1 404 Not Found"
receive_response_body.started request=<Request [b'GET']>
receive_response_body.complete
response_closed.started
response_closed.complete
close.started
close.complete
Page /microsoft_sso/callback/ took 3.1010 seconds to load.
"GET /microsoft_sso/callback/?code=0.AX0dfgh2kfit0&state=64vbg3a0-8fe5-4826-a3f4-bca7548c67d5&session_state=56xxx HTTP/1.1" 302 0
h-&state=643xxxx&session_state=56xxxbe-xxxx HTTP/1.1" 302 0
Page /admin/ took 0.0046 seconds to load.
"GET /admin/ HTTP/1.1" 302 0
"GET /admin/ HTTP/1.1" 302 0
Page /admin/login/ took 0.0057 seconds to load.
"GET /admin/login/?next=/admin/ HTTP/1.1" 200 16651
"GET /admin/login/?next=/admin/ HTTP/1.1" 200 16651
"GET /static/admin/css/base.css HTTP/1.1" 304 0
"GET /static/admin/css/base.css HTTP/1.1" 304 0
"GET /static/admin/css/login.css HTTP/1.1" 304 0
"GET /static/admin/css/login.css HTTP/1.1" 304 0
chrismaille commented 1 month ago

Hi, @vinodhkumartandrothu , thanks for the message. Regarding the two issues mentioned:

Site cannot be reached error

I can't reproduce, but it's possible this is related with some silent error on django handling the already populated user database you mentioned, which stops the framework to process the callback view. If this behavior still occurs, my suggestion is to debug the django_microsoft_sso/views.py file to better find the error context.

Looping without successful login

This occurs when user data was received from Microsoft but it's not created or found in database. I think this is because 1) MICROSOFT_SSO_AUTO_CREATE_USERS is disabled, as you stated and 2) User was not found using their User Principal Name (or Mail if you set the MICROSOFT_SSO_UNIQUE_EMAIL option). If you're using a Custom User Authentication, make sure your USERNAME_FIELD is correct configured on your custom model.

I push a new version with a new option: MICROSOFT_SSO_SHOW_FAILED_LOGIN_MESSAGE. When enabled, you will see the failed login attempt reason on browser. And this message will be always logged on terminal for now on.

Please add the MICROSOFT_SSO_SHOW_FAILED_LOGIN_MESSAGE=True on your settings.py and let me now if this can help fix this issue. New version is 4.1.0.

vinodhkumartandrothu commented 1 month ago

Hi @chrismaille Thank you for the new version of the package. It has been very helpful in debugging login issues. I have successfully tested the Microsoft SSO button for superusers, who can now log in to the admin panel, and I see data populating in the microsoft_sso_user table.

I have also developed a custom SSO button for our web application because the default button is only visible on the admin page. However, I am encountering an issue when logging into our web app as staff users or regular users through this custom SSO button. Even though these users exist in the database, I receive a "User not found" error. I'm encountering an issue with the Microsoft SSO integration. Regardless of whether I log in as a superuser, staff user, or regular user on my web app's home page, the system always redirects me to the admin page after a successful login (currently login is working for superusers). Below are the relevant logs:

2024-09-19 13:26:53.636 | INFO     | xxxx.backend:pre_create_callback:162 - Pre-create callback skipped, user creation is disabled.
2024-09-19 13:26:53.868 | WARNING  | django_microsoft_sso.utils:send_message:8 - User not found - UPN: 'testuser2@xxx.com', Email: 'None'. Auto-Create is disabled.
2024-09-20 14:42:53.594 | DEBUG    | xxx.backend:pre_validate_callback:490 - Running Pre-Validate callback for email/UPN: testuser1@xxx.com.
2024-09-20 14:42:53.834 | INFO     | xxx.backend:pre_validate_callback:496 - User testuser1@xxx.com exists in the local database.
2024-09-20 14:42:53.834 | INFO     | xxx.backend:pre_create_callback:507 - Pre-create callback skipped, user creation is disabled.
2024-09-20 14:42:53.864 | WARNING  | django_microsoft_sso.utils:send_message:8 - User not found - UPN: 'testuser1@xxx.com', Email: 'None'. Auto-Create is disabled.

I have intentionally disabled automatic user creation, as I only want to log in users who already exist in our system.

Our setup includes superusers, staff users, and regular users in the database. While all users should be able to log in through the SSO button, only staff users and superusers should be able to access the Django Admin page. I don't want to flag all users as staff, as their admin access should be based on their existing roles and permissions.

Could you please help me to integrate SSO button for all users irrespective of staff status or does it work only for superusers and staff users

chrismaille commented 1 month ago

The logs suggest the azure user with UPN testuser2@xxx.com was not found. The package use this code to search for user when auto creation is disabled: https://github.com/megalus/django-microsoft-sso/blob/65168bbf80693d7714c53a51de95eb8fae6b1e30/django_microsoft_sso/main.py#L287

If you're using a Custom Authentication, please check if the USERNAME_FIELD is correct set to the UPN field in your model. Something like this:

class MyUser(AbstractBaseUser):
    my_upn_field = models.CharField(max_length=40, unique=True)  # <- the field you store User Principal Names (UPN)
    name= models.CharField(max_length=40)
    ...
    USERNAME_FIELD = "my_upn_field"  # <- add here
vinodhkumartandrothu commented 1 month ago

I am using the default Django User model with no custom authentication. Users already exist in the database with matching emails, but I’m still encountering a "User Not Found" error during Microsoft SSO login.

The logs indicate that the Azure user with UPN (e.g., testuser1@domain.com) was not found. My MICROSOFT_SSO_UNIQUE_EMAIL is set to True.

Regardless of whether I log in as a staff user, or regular user on my web app's home page using SSO button, the system always redirects me to the admin page after User not found error.

chrismaille commented 1 month ago

UPN and Mail are different things in Azure. If your log are showing this:

2024-09-20 14:42:53.864 | WARNING  | django_microsoft_sso.utils:send_message:8 - User not found - UPN: 'testuser1@xxx.com', Email: 'None'. Auto-Create is disabled.

This means the information retrieved from Microsoft Graph are:

{
  "userPrincipalName": "testuser1@xxx.com",
  "mail": null,
}

When MICROSOFT_SSO_UNIQUE_EMAIL is True the package will compare the mail field from Graph API against the email field from User model. But because mail is empty, the user will never be found.

My advice is to set the MICROSOFT_SSO_UNIQUE_EMAIL=False and let the package compare the userPrincipalName received against the USERNAME_FIELD on your model. If you're using the default user model, this is the username field.

Please, let me know if this help to fix the issue.

vinodhkumartandrothu commented 1 month ago

Thanks for your prompt response. I tried setting MICROSOFT_SSO_UNIQUE_EMAIL=False, but still the error persists with User Not Found.

Regardless of whether I log in as a staff user, or regular user on my web app's home page using SSO button, the system always redirects me to the admin page after User not found error.

vinodhkumartandrothu commented 1 month ago

I wanted to follow up regarding the issue last week. I tried setting MICROSOFT_SSO_UNIQUE_EMAIL=False as per your suggestion, but unfortunately, I’m still encountering the "User Not Found" error.

Regardless of whether I log in as a staff user or a regular user via the SSO button on my web app’s home page, the system redirects me to the admin page after the error.

Is there anything else I should update to resolve this issue? I’d appreciate any further guidance you could provide.

Thanks again for your help!

chrismaille commented 1 month ago

Hi @vinodhkumartandrothu, about the questions:


The "User not Found" issue.

It's difficult to say, because it depends on the actual database structure. The best advice I can make is to make sure this code works for your users database: https://github.com/megalus/django-microsoft-sso/blob/65168bbf80693d7714c53a51de95eb8fae6b1e30/django_microsoft_sso/main.py#L287

Let me reproduce here:

    def find_user(self):
        if conf.MICROSOFT_SSO_UNIQUE_EMAIL:  # <- Set this to False
            query = self.user_model.objects.filter(email__iexact=self.user_email)
        else:
            username_query = {
                f"{self.username_field.attname}__iexact": self.user_principal_name  # <- Make sure the `username field` on your database is the USERNAME_FIELD of the model
            }
            query = self.user_model.objects.filter(
                Q(microsoftssouser__user_principal_name__iexact=self.user_principal_name)  # <- will not work, because you are not creating users
                | Q(**username_query)
            )
        if query.exists():
            return query.get()

The USERNAME_FIELD is the key here. If you have something like this on your database:

class MyUser(AbstractBaseUser):
    identifier = models.CharField(max_length=40, unique=True)  # <- if this is field you store the User Principal Name you got from Microsoft Graph
    ...
    USERNAME_FIELD = "identifier" # <- Then this is the field you need to define here.

If this not help, my suggestion is to rewrite the find_user method in a fork, to best match your database structure.


The redirect after User not Found issue

The package will redirect the user to the route defined in MICROSOFT_SSO_LOGIN_FAILED_URL. Default is admin:index. You need to change this option to the route name you want to redirect the user to another page.

github-actions[bot] commented 2 days ago

This issue has been marked as stale due to lack of activity. It will be closed in 7 days if no further activity occurs.