AWS SSO est enfin disponible dans la région de Tokyo, j'ai donc essayé l'authentification unique avec Django.
Créez une application SAML 2.0 personnalisée avec AWS SSO. La gestion des erreurs n'est pas effectuée pour confirmer qu'il fonctionne au minimum nécessaire.
--Utilisez ʻAWS SSO ID Storepour la source d'ID AWS SSO --Sélectionnez
Pythoncomme langage de développement --Utilisez
Django` pour le cadre d'application Web
#Créer un environnement virtuel
$ python -m venv ~/envs/example-awssso
#Commencez
$ source ~/envs/example-awssso/bin/activate
#Installation de Django
(example-awssso) $ python -m pip install Django
#Confirmation de version
(example-awssso) $ python -m django --version
3.1.1
#Création de projet
(example-awssso) $ django-admin startproject webapp .
C'est "pour le développement". Autorisez la communication SSL. Veuillez ne pas l'utiliser dans un environnement de production. J'omettrai la création de l'auto-certificat.
(example-awssso) $ pip install django-sslserver
Il y avait beaucoup de support pour l'authentification SAML, mais j'ai décidé d'essayer python3-saml
.
Résolvez la dépendance de xmlsec
avant d'installer python3-saml
.
https://github.com/onelogin/python3-saml https://pypi.org/project/xmlsec/
#résolution des dépendances xmlsec
(example-awssso) $ brew install libxml2 libxmlsec1 pkg-config
#Installation
(example-awssso) $ pip install python3-saml
AWS SSO
Configurez une application personnalisée dans AWS Management Console.
https: // localhost: 8000 / sso /
dans [URL de démarrage de l'application] de "Propriétés de l'application".https: // localhost: 8000 / acs /
dans [Application ACS URL]https: // localhost: 8000 / metadata /
dans [Application SAML Target]$ (user: subject}
, persistent
dans Subject
,
$ {user: name}, ʻunspecified
dans les attributs※6
Il existe un exemple de code de Django sur GitHub de python3-saml, veuillez donc vous y référer également.
(example-awssso) $ mkdir saml
#Créer un fichier vide pour la configuration
(example-awssso) $ touch saml/settings.json
(example-awssso) $ touch saml/advanced_settings.json
advanced_settings.json
{
"security": {
"nameIdEncrypted": false,
"authnRequestsSigned": false,
"logoutRequestSigned": false,
"logoutResponseSigned": false,
"signMetadata": false,
"wantMessagesSigned": false,
"wantAssertionsSigned": false,
"wantNameId": true,
"wantNameIdEncrypted": false,
"signatureAlgorithm": "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256",
"digestAlgorithm": "http://www.w3.org/2001/04/xmlenc#sha256"
},
"contactPerson": {
"technical": {
"givenName": "technical_name",
"emailAddress": "[email protected]"
},
"support": {
"givenName": "support_name",
"emailAddress": "[email protected]"
}
},
"organization": {
"en-US": {
"name": "sp_test",
"displayname": "SP test",
"url": "https://localhost:8000"
}
}
}
settings.json
ʻEdit et enregistrez les paramètres suivants à partir du contenu du fichier de métadonnées AWS SSO SAML `.
sp
idp
ʻSet à partir du contenu du fichier de métadonnées AWS SSO SAML. Les valeurs entre
()` sont les valeurs d'attribut du fichier de métadonnées.
{
"strict": true,
"debug": true,
"sp": {
"entityId": "https://localhost:8000/metadata/",
"assertionConsumerService": {
"url": "https://localhost:8000/acs/",
"binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
},
"singleLogoutService": {
"url": "https://localhost:8000/sls/",
"binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
},
"NameIDFormat": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent",
"x509cert": "",
"privateKey": ""
},
"idp": {
"entityId": "https://portal.sso.ap-northeast-1.amazonaws.com/saml/assertion/<AWS SSO ID>",
"singleSignOnService": {
"url": "https://portal.sso.ap-northeast-1.amazonaws.com/saml/assertion/<AWS SSO ID>",
"binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
},
"singleLogoutService": {
"url": "https://portal.sso.ap-northeast-1.amazonaws.com/saml/logout/<AWS SSO ID>",
"binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
},
"x509cert": "<Certificat AWS SSO>"
}
}
webapp/settings.py
Ajoutez les paramètres du répertoire de modèles.
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
- 'DIRS': [],
+ 'DIRS': [
+ os.path.join(BASE_DIR, 'templates')
+ ],
Ajouter d'autres paramètres au fichier
+ INSTALLED_APPS += ['sslserver']
+
+ # session
+ SESSION_ENGINE = 'django.contrib.sessions.backends.file'
+
+ # ssl
+ SECURE_SSL_REDIRECT = True
+ SESSION_COOKIE_SECURE = True
+ CSRF_COOKIE_SECURE = True
+
+ # python3-saml
+ SAML_FOLDER = os.path.join(BASE_DIR, 'saml')
+
+ # login, logout
+ LOGIN_REDIRECT_URL = '/'
+ LOGOUT_REDIRECT_URL = '/'
webapp/urls.py
Définissez l'URL requise pour l'authentification unique. views.py sera nouvellement créé après cela.
from django.contrib import admin
from django.urls import path
+ from django.contrib.auth.views import LogoutView
+ from .views import index, sso, acs, metadata
urlpatterns = [
path('admin/', admin.site.urls),
+ path('', index, name='index'),
+ path('sso/', sso, name='sso'),
+ path('acs/', acs, name='acs'),
+ path('logout/', LogoutView.as_view(), name='logout'),
+ path('metadata/', metadata),
]
webapp/views.py
Comme mentionné dans le commentaire source, créez la vue suivante.
(example-awssso) $ touch webapp/views.py
from django.conf import settings
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseServerError
from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt
from onelogin.saml2.auth import OneLogin_Saml2_Auth
from onelogin.saml2.settings import OneLogin_Saml2_Settings
from onelogin.saml2.utils import OneLogin_Saml2_Utils
def init_saml_auth(params):
"""Initialisation du client SAML
Paramètres d'initialisation du client, saml/settings.json ・ saml/advanced_settings.Initialiser avec le fichier json
"""
auth = OneLogin_Saml2_Auth(params, custom_base_path=settings.SAML_FOLDER)
return auth
def prepare_django_request(request):
"""Obtenir les paramètres d'initialisation du client SAML
Générer les paramètres d'initialisation du client SAML à partir de l'objet de requête HTTP
"""
params = {
'https': 'on' if request.is_secure() else 'off',
'http_host': request.META['HTTP_HOST'],
'script_name': request.META['PATH_INFO'],
'server_port': request.META['SERVER_PORT'],
'get_data': request.GET.copy(),
'post_data': request.POST.copy()
}
return params
def index(request):
"""Affichage de la page TOP
Rendre la page TOP
"""
#Initialisation des paramètres de contexte
attributes = False
if 'samlUserdata' in request.session:
if len(request.session['samlUserdata']) > 0:
attributes = request.session['samlUserdata'].items()
return render(request, 'index.html', { 'attributes': attributes, })
@csrf_exempt
def sso(request):
"""Redirection AWS SSO
Redirection vers AWS SSO
"""
#Obtenir les paramètres d'initialisation
prepare_params = prepare_django_request(request)
#Initialisation
auth = init_saml_auth(prepare_params)
return HttpResponseRedirect(auth.login())
@csrf_exempt
def acs(request):
"""Vérification des assertions
Vérifiez que l'utilisateur est autorisé à accéder à l'application
"""
#Obtenir les paramètres d'initialisation
prepare_params = prepare_django_request(request)
#Initialisation
auth = init_saml_auth(prepare_params)
request_id = None
if 'AuthNRequestID' in request.session:
request_id = request.session['AuthNRequestID']
auth.process_response(request_id=request_id)
errors = auth.get_errors()
if not errors:
if 'AuthNRequestID' in request.session:
del request.session['AuthNRequestID']
request.session['samlUserdata'] = auth.get_attributes()
request.session['samlNameId'] = auth.get_nameid()
request.session['samlNameIdFormat'] = auth.get_nameid_format()
request.session['samlNameIdNameQualifier'] = auth.get_nameid_nq()
request.session['samlNameIdSPNameQualifier'] = auth.get_nameid_spnq()
request.session['samlSessionIndex'] = auth.get_session_index()
return HttpResponseRedirect(auth.redirect_to('/'))
def metadata(request):
"""Affichage des métadonnées SP
Métadonnées de sortie
"""
saml_settings = OneLogin_Saml2_Settings(settings=None, custom_base_path=settings.SAML_FOLDER, sp_validation_only=True)
metadata = saml_settings.get_sp_metadata()
errors = saml_settings.validate_metadata(metadata)
if len(errors) == 0:
return HttpResponse(content=metadata, content_type='text/xml')
else:
return HttpResponseServerError(content=', '.join(errors))
# SECRET_Réglage KEY
(example-awssso) $ export DJANGO_SECRET_KEY='01234567890123456789012345678901234567890123456789'
#Démarrez Django
(example-awssso) $ python ./manage runsslserver 0.0.0.0:8000 --certificate ./certs/localhost.crt.pem --key ./certs/localhost.key.pem
Accédez à https: // localhost: 8000 / `.
Sélectionnez [Connexion]. Puisqu'il sera expurgé dans AWS SSO, connectez-vous en tant qu'utilisateur créé dans le magasin d'ID.
Les informations utilisateur enregistrées dans la session à partir de la réponse SAML s'affichent à l'écran.
Il sera possible de gérer de manière centralisée ce que les utilisateurs IAM ont utilisé pour accéder à AWS Management Console, et de gérer facilement l'accès et les utilisateurs pour tous les comptes suspendus à AWS Organizations.
En outre, l'API d'attribution de compte d'AWS SSO et la prise en charge de CloudFormation ont été ajoutées l'autre jour, il semble donc que l'automatisation puisse être prise en charge de manière flexible.
Recommended Posts