Compare commits
2 Commits
e5682c2573
...
ef733cb7bf
| Author | SHA1 | Date | |
|---|---|---|---|
| ef733cb7bf | |||
| 88afd5d307 |
@@ -1,4 +1,4 @@
|
||||
# SSO with Allauth & Casdoor Pattern v1.0.0
|
||||
# SSO with Allauth & Casdoor Pattern v1.02
|
||||
|
||||
Standardizes OIDC-based Single Sign-On using Django Allauth and Casdoor, covering adapter customization, user provisioning, group mapping, superuser protection, and configurable local-login fallback. Used by the `core` Django application.
|
||||
|
||||
@@ -35,6 +35,7 @@ Every SSO implementation following this pattern must provide these files:
|
||||
| Local account adapter | `<app>/adapters.py` | Disable local signup, authentication logging |
|
||||
| Management command | `<app>/management/commands/create_sso_groups.py` | Idempotent group + permission creation |
|
||||
| Login template | `templates/account/login.html` | SSO button + conditional local login form |
|
||||
| SSO signup template | `templates/socialaccount/signup.html` | Email confirmation step for first-time SSO users |
|
||||
| Context processor | `<app>/context_processors.py` | Expose `CASDOOR_ENABLED` / `ALLOW_LOCAL_LOGIN` to templates |
|
||||
| SSL patch (optional) | `<app>/ssl_patch.py` | Development-only SSL bypass |
|
||||
|
||||
@@ -194,7 +195,7 @@ The social account adapter is the core of the pattern. It handles user provision
|
||||
|
||||
```python
|
||||
from allauth.socialaccount.adapter import DefaultSocialAccountAdapter
|
||||
from allauth.exceptions import ImmediateHttpResponse
|
||||
from allauth.core.exceptions import ImmediateHttpResponse
|
||||
from django.contrib.auth.models import User, Group
|
||||
from django.contrib import messages
|
||||
from django.shortcuts import redirect
|
||||
@@ -440,6 +441,73 @@ The login template shows an SSO button when Casdoor is enabled and conditionally
|
||||
|
||||
---
|
||||
|
||||
## SSO Signup Template
|
||||
|
||||
When a new SSO user has no existing account, allauth redirects them to `accounts/3rdparty/signup/` to confirm their email before the account is created. Without a custom template this page renders with no styling.
|
||||
|
||||
Create `templates/socialaccount/signup.html` extending the project base:
|
||||
|
||||
```html
|
||||
{% extends "<app>/base.html" %}
|
||||
|
||||
{% block title %}Complete Sign Up — {{ themis_app_name }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="flex justify-center items-center min-h-[60vh]">
|
||||
<div class="card bg-base-200 shadow-xl w-full max-w-md">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title text-2xl justify-center mb-2">Complete Sign Up</h2>
|
||||
<p class="text-center text-base-content/70 mb-4">
|
||||
Confirm your email address to finish signing in with SSO.
|
||||
</p>
|
||||
|
||||
{% if form.errors %}
|
||||
<div class="alert alert-error mb-4">
|
||||
<span>Please correct the errors below.</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<form method="post" action="{{ action_url }}">
|
||||
{% csrf_token %}
|
||||
|
||||
<div class="form-control mb-6">
|
||||
<label class="label" for="id_email">
|
||||
<span class="label-text">Email</span>
|
||||
</label>
|
||||
<input type="email" name="email" id="id_email"
|
||||
class="input input-bordered w-full{% if form.email.errors %} input-error{% endif %}"
|
||||
value="{{ form.email.value|default:'' }}"
|
||||
autocomplete="email" required>
|
||||
{% if form.email.errors %}
|
||||
<label class="label">
|
||||
<span class="label-text-alt text-error">{{ form.email.errors|join:", " }}</span>
|
||||
</label>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="form-control mt-2">
|
||||
<button type="submit" class="btn btn-primary w-full">Complete Sign Up</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
```
|
||||
|
||||
Key context variables allauth provides to this template:
|
||||
|
||||
| Variable | Description |
|
||||
|----------|-------------|
|
||||
| `form` | `SignupForm` with a single `email` field pre-populated from the OIDC claim |
|
||||
| `action_url` | POST target (`/accounts/3rdparty/signup/`) — always use this, not a hard-coded path |
|
||||
| `sociallogin` | The in-progress social login object (rarely needed in the template) |
|
||||
|
||||
> **Why this page exists:** `SOCIALACCOUNT_AUTO_SIGNUP = True` skips it when the IdP provides a valid email. It only appears when allauth cannot confirm the email (e.g. the IdP omitted it or there is a conflict with an existing account).
|
||||
|
||||
---
|
||||
|
||||
## Context Processor
|
||||
|
||||
Exposes SSO settings to every template:
|
||||
@@ -701,7 +769,7 @@ class CasdoorAdapterTest(TestCase):
|
||||
|
||||
def test_superuser_sso_login_blocked(self):
|
||||
"""pre_social_login must raise ImmediateHttpResponse for superusers."""
|
||||
from allauth.exceptions import ImmediateHttpResponse
|
||||
from allauth.core.exceptions import ImmediateHttpResponse
|
||||
user = User.objects.create_superuser(
|
||||
'admin@example.com', 'admin@example.com', 'pass'
|
||||
)
|
||||
Reference in New Issue
Block a user