[PYTHON] Authentification unique à l'application Django avec AWS SSO

introduction

AWS SSO est enfin disponible dans la région de Tokyo, j'ai donc essayé l'authentification unique avec Django.

Code source-GitHub

Prérequis et environnement d'exploitation

Aperçu

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.

Politique etc.

--Utilisez ʻAWS SSO ID Storepour la source d'ID AWS SSO --SélectionnezPythoncomme langage de développement --UtilisezDjango` pour le cadre d'application Web

installer

#Créer un environnement virtuel
$ python -m venv ~/envs/example-awssso

#Commencez
$ source ~/envs/example-awssso/bin/activate

Installation, création de projet

#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 .

Installer (ssl)

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

Installation (python3-saml)

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.

  1. Sélectionnez [Ajouter une nouvelle application] dans "Applications"
  2. Sélectionnez [Ajouter une application SAML 2.0 personnalisée] dans le "Catalogue d'applications AWS SSO".
  3. Sélectionnez [Télécharger] de «Fichier de métadonnées AWS SSO SAML» pour télécharger le fichier de métadonnées.
  4. Entrez https: // localhost: 8000 / sso / dans [URL de démarrage de l'application] de "Propriétés de l'application".
  5. Sous Métadonnées d'application, vous pouvez saisir manuellement les valeurs de métadonnées si vous ne disposez pas d'un fichier de métadonnées. ] Est sélectionné
  6. Entrez https: // localhost: 8000 / acs / dans [Application ACS URL]
  7. Entrez https: // localhost: 8000 / metadata / dans [Application SAML Target]
  8. Sélectionnez l'application enregistrée et sélectionnez la balise [Attribute Mapping].
  9. Entrez $ (user: subject}, persistent dans Subject
  10. Entrez ʻusername, $ {user: name}, ʻunspecified dans les attributs
  11. Sélectionnez Enregistrer les modifications
  12. Sélectionnez [Ajouter un utilisateur] dans "Utilisateurs" pour ajouter un utilisateur.
  13. Sélectionnez l'onglet [Utilisateurs affectés] dans [Applications] et ajoutez l'utilisateur créé à partir de [Attribuer un utilisateur].

※6

image.png

Configuration de l'application

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))

Contrôle de fonctionnement

# 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 / `.

image.png

Sélectionnez [Connexion]. Puisqu'il sera expurgé dans AWS SSO, connectez-vous en tant qu'utilisateur créé dans le magasin d'ID.

image.png

Les informations utilisateur enregistrées dans la session à partir de la réponse SAML s'affichent à l'écran.

à la fin

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

Authentification unique à l'application Django avec AWS SSO
Étapes pour développer Django avec VSCode
Mesurer la couverture des applications Django avec Coverage.py
Enregistrer l'application Django dans le projet
Déployer l'application Django avec Docker
Standardiser le HTML à louer avec Django
Déployer l'application Django sur Heroku
Comment démarrer avec Django
Créer une application Web avec Django
Lancement d'une application Web sur AWS avec django et modification des tâches
Gérez vos données avec AWS RDS
Créez une application Django sur Docker et déployez-la sur AWS Fargate
Jusqu'à ce que l'application Django (+ MySQL) soit publiée sur AWS EC2 (+ RDS (+ S3))
Comment effectuer un traitement arithmétique avec le modèle Django
Notes d'étape pour démarrer avec django
Votre propre client Twitter réalisé avec Django
Je veux jouer avec aws avec python
Pour importer votre propre module avec jupyter
Développement d'applications à l'aide de SQLite avec Django (PTVS)
Création de la première application avec Django startproject
Connectez-vous à s3 avec AWS Lambda Python
J'ai fait une application WEB avec Django
[Python] Présentez UIKit3 au projet Django
Essayez de créer votre propre AWS-SDK avec bash
Le moyen le plus simple de démarrer avec Django
Divisez les données en unités de type projet avec Django (3)
Comment développer une application de panier avec Django
Donnez vie à votre vie de manière procédurale avec les scripts Blender
Comment implémenter "named_scope" de RubyOnRails avec Django
Connectez-vous facilement à AWS avec plusieurs comptes
Divisez les données en unités de type projet avec Django
Créez une application Hello World avec un seul fichier avec django
AWS Step Functions pour apprendre avec un exemple
[Introduction à l'application Udemy Python3 +] 9. Tout d'abord, imprimez avec print
Étapes pour installer votre propre bibliothèque avec pip
Les débutants essaient de créer une application Web de combat en ligne Othello avec Django + React + Bootstrap (1)
[Mémo d'apprentissage] Comment créer une application avec Django ~ Jusqu'à ce que Hello World soit affiché ~
[Mémo d'apprentissage] Comment créer une application avec Django ~ De l'environnement virtuel au push vers github ~