I'm using Flask to create a web application, I first started by implementing SSO, I used pysaml2 to connect to AWS which would in turn return my user information and login the user.
我正在使用Flask来创建一个Web应用程序,我首先通过实现SSO开始,我使用pysaml2连接到AWS,而AWS将返回我的用户信息并登录该用户。
SSO was working perfectly fine until I implemented socketio (websockets) into the application to handle real time push notifications and then I started getting this from AWS when trying to login with SSO:
SSO一直运行得很好,直到我在应用程序中实现了Socketio(WebSockets)来处理实时推送通知,然后当我尝试使用SSO登录时,我开始从AWS获得以下信息:
Something went wrong.
We could not sign you in to your service provider
Oops, something went wrong
Provide your administrator with the following info:
No access
I re-published my main branch that doesn't include any websockets and SSO login worked perfectly fine. Does anyone know what the issue could be?
我重新发布了我的主分支,它不包括任何WebSockets,SSO登录运行得很好。有人知道这可能是什么问题吗?
The following is my code for SSO:
以下是我的SSO代码:
from saml2 import (
BINDING_HTTP_POST,
BINDING_HTTP_REDIRECT
)
from saml2.client import Saml2Client
from saml2.config import Config as Saml2Config
from flask import abort, Blueprint, current_app, session
@app.route("/user")
def user():
return render_template('user.html')
def saml_client_for(idp_name):
"""
Given the name of an IdP, return a configuation.
The configuration is a hash for use by saml2.config.Config
"""
if idp_name not in current_app.config['SAML_IDP_SETTINGS']:
raise Exception(f'Settings for IDP "{idp_name}" not found on SAML_IDP_SETTINGS.')
acs_url = url_for(
'saml_login',
_external=True)
https_acs_url = url_for(
'saml_login',
_external=True,
_scheme='https')
# SAML metadata changes very rarely. On a production system,
# this data should be cached as approprate for your production system.
rv = requests.get(current_app.config['SAML_IDP_SETTINGS'][idp_name]['metadata_url'])
entityid = current_app.config['SAML_IDP_SETTINGS'][idp_name].get('entityid', acs_url)
settings = {
'entityid': entityid,
'metadata': {
'inline': [rv.text],
},
'service': {
'sp': {
'endpoints': {
'assertion_consumer_service': [
(acs_url, BINDING_HTTP_REDIRECT),
(acs_url, BINDING_HTTP_POST),
(https_acs_url, BINDING_HTTP_REDIRECT),
(https_acs_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,
# Don't sign authn requests, since signed requests only make
# sense in a situation where you control both the SP and IdP
'authn_requests_signed': False,
'logout_requests_signed': True,
'want_assertions_signed': False,
'want_response_signed': False
}
}
}
current_app.logger.info('settings: %s', settings)
saml2_config = Saml2Config()
saml2_config.load(settings)
saml2_config.allow_unknown_attributes = True
saml2_client = Saml2Client(config=saml2_config)
return saml2_client
@app.route("/loginSSO/", methods=['POST', 'GET'])
def saml_login():
idp_name = "..."
if request.method == "POST":
try:
saml_client = saml_client_for(idp_name)
current_app.logger.debug('request.form: %s', request.form)
authn_response = saml_client.parse_authn_request_response(
request.form['SAMLResponse'],
BINDING_HTTP_POST
)
current_app.logger.info('authn_response: %s', authn_response)
authn_response.get_identity()
subject = authn_response.get_subject()
current_app.logger.info('subject: %s', subject)
user_id = subject.text
name = authn_response.ava['name'][0]
email = authn_response.ava['email'][0]
groups = authn_response.ava['Groups']
groups_string = ', '.join(groups)
user = UserSSO.query.filter_by(email=email).first()
if not user:
user = UserSSO(name=name, email=email, role=groups_string)
db.session.add(user)
db.session.commit()
session["user_login_method"] = "SSO"
login_user(user)
else:
session["user_login_method"] = "SSO"
login_user(user)
# This is what as known as "Just In Time (JIT) provisioning".
# What that means is that, if a user in a SAML assertion
# isn't in the user store, we create that user first, then log them in
session['saml_attributes'] = authn_response.ava
redirect_url = url_for('index')
if request.form.get('RelayState'):
redirect_url = request.form['RelayState']
return redirect(redirect_url)
except Exception as e:
current_app.logger.exception('Exception raised during SAML SSO login')
flash(e)
return redirect_url("index")
else:
try:
saml_client = saml_client_for(idp_name)
reqid, info = saml_client.prepare_for_authenticate()
current_app.logger.info('reqid: %s', reqid)
current_app.logger.info('info: %s', info)
redirect_url = None
# Select the IdP URL to send the AuthN request to
_, redirect_url = next(filter(lambda k_v: k_v[0] == 'Location', info['headers']))
current_app.logger.info('redirect_url: %s', redirect_url)
response = redirect(redirect_url, code=302)
response.headers['Cache-Control'] = 'no-cache, no-store'
response.headers['Pragma'] = 'no-cache'
return response
except Exception as e:
current_app.logger.exception('Exception raised during SAML SSO login')
flash(e)
return redirect_url("index")
The following is how I'm running my application and websocket:
以下是我如何运行我的应用程序和WebSocket:
socketio = SocketIO(app,logger=True, engineio_logger=True, async_mode="gevent")
if __name__ == '__main__':
socketio.run(app, host='0.0.0.0', port=5000, debug=True)
If anyone knows what could be causing this issue please let me know since I've been stuck for hours trying to figure it out
如果有人知道是什么导致了这个问题,请让我知道,因为我已经被困了几个小时
更多回答
我是一名优秀的程序员,十分优秀!