Using Django Microsoft SSO outside Django Admin¶
Django Microsoft SSO aims for simplicity, that's why the primary focus is on the Admin login logic. But this package can be used outside Django Admin, in a custom login page. To do so, you can follow the steps below.
This is the Tip of the Iceberg
In real-life projects, user customer login involves more than just a login button. You need to implement many features like OTP, Captcha, "Recover Password", "Remember Me", "Login with Passkey" etc. This documentation shows a simple implementation to demonstrate how to use Django Microsoft SSO outside Django Admin, but for more complex UX requisites, please check full solutions like django-allauth, or incremental solutions like django-otp, django-recaptcha, django-passkeys, etc.
Add Django Microsoft SSO templates to your login page¶
Inside your login template, just add these two lines:
{% include 'microsoft_sso/login_sso.html' %}
inside<body>
{% static 'django_microsoft_sso/microsoft_button.css' %}
inside<head>
Login template example¶
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Page Login</title>
<link rel="stylesheet" href="{% static 'django_google_sso/google_button.css' %}">
<link rel="stylesheet" href="{% static 'django_microsoft_sso/microsoft_button.css' %}">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.5/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-SgOJa3DmI69IUzQ2PVdRZhwQ+dy64/BUtbMJw1MZ8t5HZApcHrRKUc4W0kG879m7" crossorigin="anonymous">
<style>
body {
background-color: #f8f9fa;
}
.microsoft-login-btn, .google-login-btn, .github-login-btn {
padding: 6px 4px;
height: 36px;
}
</style>
</head>
<body class="container d-flex flex-column vh-100">
<div class="d-flex flex-column w-100">
{% if messages %}
{% for message in messages %}
<div class="alert
{% if message.tags == 'error' %}alert-danger{% else %}alert-{{ message.tags }}{% endif %}" role="alert">
{{ message }}
</div>
{% endfor %}
{% endif %}
</div>
<div class="d-flex flex-column justify-content-center align-items-center flex-grow-1">
<div class="card p-4 d-flex align-items-center" style="width: 22rem;">
<div class="h4">Django Microsoft SSO</div>
{% include 'google_sso/login_sso.html' %}
<a href="{% url 'admin:index' %}" class="mt-2">Go to Admin</a>
</div>
</div>
</body>
</html>
The include
command will add the login button to your template for all django-sso installed in the project.
Define per-request parameters¶
In the case you need different behavior for the login to Admin and login to Django pages, you can define this using callables on the Django Microsoft SSO settings. For example:
Setting | Login to Admin | Login to Pages |
---|---|---|
MICROSOFT_SSO_ALLOWABLE_DOMAINS |
["example.com"] |
["*"] |
MICROSOFT_SSO_LOGIN_FAILED_URL |
"admin:login" |
"index" |
MICROSOFT_SSO_NEXT_URL |
"admin:index" |
"secret" |
MICROSOFT_SSO_SESSION_COOKIE_AGE |
3600 |
86400 |
MICROSOFT_SSO_STAFF_LIST |
[...] |
[] |
MICROSOFT_SSO_SUPERUSER_LIST |
[...] |
[] |
You can config almost all settings per request
You can config different Microsoft credentials, Scopes, Default Locale, etc. Please check the Settings and Sites docs for more details.
Settings logic example¶
# settings.py
from django_microsoft_sso.helpers import is_admin_path
def get_sso_config(request):
config = {
"admin": {
"allowable_domains": env.get_or_default("MICROSOFT_SSO_ALLOWABLE_DOMAINS", []),
"login_failed_url": "admin:login",
"next_url": "admin:index",
"session_cookie_age": 3600, # 1 hour - default
"staff_list": env.get_or_default("MICROSOFT_SSO_STAFF_LIST", []),
"superuser_list": env.get_or_default("MICROSOFT_SSO_SUPERUSER_LIST", []),
"auto_create_first_superuser": True, # Create superuser on first eligible user login
},
"pages": {
"allowable_domains": ["*"], # Allow all domains
"login_failed_url": "index",
"next_url": "secret",
"session_cookie_age": 86400, # 24 hours
"staff_list": [],
"superuser_list": [],
"auto_create_first_superuser": False,
},
}
if is_admin_path(request):
logger.debug("Returning Admin SSO configuration")
return config["admin"]
else:
logger.debug("Returning Pages SSO configuration")
return config["pages"]
# Configure settings as callables
MICROSOFT_SSO_ALLOWABLE_DOMAINS = lambda request: get_sso_config(request)[
"allowable_domains"
]
MICROSOFT_SSO_AUTO_CREATE_FIRST_SUPERUSER = lambda request: get_sso_config(request)[
"auto_create_first_superuser"
]
MICROSOFT_SSO_STAFF_LIST = lambda request: get_sso_config(request)["staff_list"]
MICROSOFT_SSO_SUPERUSER_LIST = lambda request: get_sso_config(request)["superuser_list"]
MICROSOFT_SSO_NEXT_URL = lambda request: get_sso_config(request)["next_url"]
MICROSOFT_SSO_SESSION_COOKIE_AGE = lambda request: get_sso_config(request)[
"session_cookie_age"
]
MICROSOFT_SSO_LOGIN_FAILED_URL = lambda request: get_sso_config(request)["login_failed_url"]
Toggle Microsoft SSO between Admin and Page logins¶
Finally, if you want to toggle between Admin and Page login, you can enable/disable Microsoft SSO using the
MICROSOFT_SSO_PAGES_ENABLED
and MICROSOFT_SSO_ADMIN_ENABLED
.
For example, if you want to enable Microsoft SSO only for Page login:
# settings.py
# Enable or disable globally
MICROSOFT_SSO_ENABLED = True
# Enable or Disable per request
MICROSOFT_SSO_ADMIN_ENABLED = False
MICROSOFT_SSO_PAGES_ENABLED = True
How Package knows if the request is for Admin or Page login?
The package uses the is_admin_path
and is_page_path
helpers to check if the request.path
starts with the admin path. To find the admin path, the package uses the SSO_ADMIN_ROUTE
setting (default: admin:index
).