2015-01-13 7 views
11

में SAML 2.0 सेवा प्रदाता मैं पाइथन में एक SAML 2.0 आधारित सेवा प्रदाता को लागू करने के लिए देख रहा हूं।पायथन

मेरे वेब ऐप्स वर्तमान में सभी फ्लास्क एप्लिकेशन हैं। मैं एक फ्लास्क ब्लूप्रिंट/सजावट बनाने की योजना बना रहा हूं जो मुझे पूर्ववर्ती अनुप्रयोगों में एकल साइन-ऑन क्षमताओं को छोड़ने की अनुमति देता है।

मैंने python-saml को बड़े पैमाने पर देखा है और दुर्भाग्यवश ऐसे निर्भरता मुद्दे हैं जो हल करने योग्य नहीं हैं, क्योंकि मेरे पास बहुत सारे पूर्ववर्ती सर्वर/ऐप्स हैं जो वातावरण संगत नहीं होंगे।

PySAML2 ऐसा लगता है कि यह काम कर सकता है, हालांकि वहां बहुत कम दस्तावेज है, और कौन सा दस्तावेज उपलब्ध है मुझे समझने में परेशानी है। फ्लास्क ऐप में उपयोग किए गए PySAML2 के कोई उदाहरण नहीं हैं।

पहचान प्रदाता मेरे पास ओक्टा है। मेरे पास ओक्टा सेट अप है ताकि ओक्टा में लॉगिन करने के बाद, मुझे अपने ऐप पर रीडायरेक्ट कर दिया गया है।

कोई भी पीईएसएएमएल 2 का उपयोग करने पर कोई सलाह दे सकता है, या शायद एसएएमएल 2.0 का उपयोग कर उपयोगकर्ता को सर्वोत्तम प्रमाणीकृत करने के बारे में सलाह दे सकता है जो मेरे आवेदन पर जा रहा है?

उत्तर

14

अपडेट: using PySAML2 with Okta पर विस्तृत स्पष्टीकरण अब developer.okta.com पर है।

नीचे पायथन/फ्लास्क में एक SAML एसपी लागू करने के लिए कुछ नमूना कोड है। यह नमूना कोड कई चीजों को प्रदर्शित करता है:

  1. एकाधिक आईडीपी का समर्थन करना।
  2. उपयोगकर्ता प्रबंधन के लिए Flask-Login का उपयोग करना।
  3. श्रोताओं के प्रतिबंध के रूप में "एसएसओ यूआरएल" का उपयोग करना (आईडीपी पर कॉन्फ़िगरेशन को सरल बनाने के लिए)।
  4. बस उपयोगकर्ताओं के समय प्रावधान ("SAML JIT")
  5. विशेषता वक्तव्य में अतिरिक्त उपयोगकर्ता जानकारी पास करना।

क्या है प्रदर्शन नहीं सपा शुरू की प्रमाणन अनुरोध कर रही है - मैं बाद में उस के साथ अनुसरण करेंगे।

किसी बिंदु पर, मुझे उम्मीद है कि pysaml2 के चारों ओर एक रैपर बनाने की उम्मीद है जिसने डिफ़ॉल्ट पर विचार किया है।

आखिरकार, पायथन-सैम की तरह, pysaml2 लाइब्रेरी xmlsec1 बाइनरी का उपयोग करती है। इससे आपके सर्वर वातावरण में निर्भरता के मुद्दे भी हो सकते हैं। यदि ऐसा है, तो आप को signxml लाइब्रेरी के साथ बदलना चाहते हैं।

नीचे दिए नमूने में सब कुछ निम्नलिखित सेटअप के साथ काम करना चाहिए:

$ virtualenv venv 
$ source venv/bin/activate 
$ pip install flask flask-login pysaml2 

अंत में, आप इस काम करने के लिए Okta पक्ष पर बातें करने के लिए करने की आवश्यकता होगी।

पहला: में अपने ओकेटा एप्लिकेशन कॉन्फ़िगरेशन के सामान्य टैब में, "फर्स्टनाम" और "अंतिम नाम" विशेषता विवरण भेजने के लिए एप्लिकेशन को कॉन्फ़िगर करें।Adding Attribute Statements to an Okta application

दूसरा: एकल साइन अपने Okta आवेदन विन्यास के टैब पर में, यूआरएल की लेते हैं और उन्हें example.okta.com.metadata नामक फ़ाइल में डाल दिया। आप इसे नीचे दिए गए आदेश की तरह कर सकते हैं।

# -*- coding: utf-8 -*- 
import base64 
import logging 
import os 
import urllib 
import uuid 
import zlib 

from flask import Flask 
from flask import redirect 
from flask import request 
from flask import url_for 
from flask.ext.login import LoginManager 
from flask.ext.login import UserMixin 
from flask.ext.login import current_user 
from flask.ext.login import login_required 
from flask.ext.login import login_user 
from saml2 import BINDING_HTTP_POST 
from saml2 import BINDING_HTTP_REDIRECT 
from saml2 import entity 
from saml2.client import Saml2Client 
from saml2.config import Config as Saml2Config 

# PER APPLICATION configuration settings. 
# Each SAML service that you support will have different values here. 
idp_settings = { 
    u'example.okta.com': { 
     u"metadata": { 
      "local": [u'./example.okta.com.metadata'] 
     } 
    }, 
} 
app = Flask(__name__) 
app.secret_key = str(uuid.uuid4()) # Replace with your secret key 
login_manager = LoginManager() 
login_manager.setup_app(app) 
logging.basicConfig(level=logging.DEBUG) 
# Replace this with your own user store 
user_store = {} 


class User(UserMixin): 
    def __init__(self, user_id): 
     user = {} 
     self.id = None 
     self.first_name = None 
     self.last_name = None 
     try: 
      user = user_store[user_id] 
      self.id = unicode(user_id) 
      self.first_name = user['first_name'] 
      self.last_name = user['last_name'] 
     except: 
      pass 


@login_manager.user_loader 
def load_user(user_id): 
    return User(user_id) 


@app.route("/") 
def main_page(): 
    return "Hello" 


@app.route("/saml/sso/<idp_name>", methods=['POST']) 
def idp_initiated(idp_name): 
    settings = idp_settings[idp_name] 
    settings['service'] = { 
     'sp': { 
      'endpoints': { 
       'assertion_consumer_service': [ 
        (request.url, BINDING_HTTP_REDIRECT), 
        (request.url, BINDING_HTTP_POST) 
       ], 
      }, 
      # Don't verify that the incoming requests originate from us via 
      # the built-in cache for authn request ids in pysaml2 
      'allow_unsolicited': True, 
      'authn_requests_signed': False, 
      'logout_requests_signed': True, 
      'want_assertions_signed': True, 
      'want_response_signed': False, 
     }, 
    } 

    spConfig = Saml2Config() 
    spConfig.load(settings) 
    spConfig.allow_unknown_attributes = True 

    cli = Saml2Client(config=spConfig) 
    try: 
     authn_response = cli.parse_authn_request_response(
      request.form['SAMLResponse'], 
      entity.BINDING_HTTP_POST) 
     authn_response.get_identity() 
     user_info = authn_response.get_subject() 
     username = user_info.text 
     valid = True 
    except Exception as e: 
     logging.error(e) 
     valid = False 
     return str(e), 401 

    # "JIT provisioning" 
    if username not in user_store: 
     user_store[username] = { 
      'first_name': authn_response.ava['FirstName'][0], 
      'last_name': authn_response.ava['LastName'][0], 
      } 
    user = User(username) 
    login_user(user) 
    # TODO: If it exists, redirect to request.form['RelayState'] 
    return redirect(url_for('user')) 


@app.route("/user") 
@login_required 
def user(): 
    msg = u"Hello {user.first_name} {user.last_name}".format(user=current_user) 
    return msg 


if __name__ == "__main__": 
    port = int(os.environ.get('PORT', 5000)) 
    if port == 5000: 
     app.debug = True 
    app.run(host='0.0.0.0', port=port) 
+0

धन्यवाद इस के लिए एक बहुत:

$ curl [the metadata url for your Okta application] > example.okta.com.metadata 

Where to find the metadata url for an Okta application

यहाँ आप अपने अजगर/बोतल आवेदन IdP SAML अनुरोधों शुरू की संभाल करने के लिए क्या करना है। यह बहुत उपयोगी है। यदि आपके पास एक एसपी शुरू हुआ उदाहरण है जो शानदार होगा! क्या आप यहां pysaml2 का नवीनतम संस्करण भी उपयोग कर रहे हैं? – steve

+0

आपका स्वागत है! हां, मैं कुछ दिनों में एक एसपी शुरूआती उदाहरण जोड़ने की योजना बना रहा हूं। –

+0

मुझे यकीन नहीं है कि पीआईएसएमएल 2 का संस्करण नवीनतम है, 'पीआईपी फ्रीज' के अनुसार उपर्युक्त उदाहरण में मैंने जो संस्करण इस्तेमाल किया था वह है 'pysaml2 == 2.2.0' –