我正在使用开源项目https://github.com/jpf/okta-pysaml2-example来学习okta、saml、sso和flask。我已在 okta 中进行了所需的应用程序集成设置。当我启动 flast Web 服务器作为服务提供商并使用 ngrok 访问 http://localhost:5000 时,我被重定向到 okta 登录页面,在其中填写用户/密码。单击提交按钮后,okta 会登陆 https://dev-023456-admin.okta.com/admin/getting-started。然而,理想情况下,okta 应该重定向回服务提供商。这里出了什么问题?我已经在两侧正确配置了元数据。这里可能有什么问题?我怎样才能缩小问题范围?
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" entityID="http://www.okta.com/abcdefghijklm">
<md:IDPSSODescriptor WantAuthnRequestsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<md:KeyDescriptor use="signing">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
<ds:X509Certificate>MIIDqDCCApCgAwIBAgIGAX2Vjf7/MA0GCSqGSIb3DQEBCwUAMIGUMQswCQYDVQQGEwJVUzETMBEG A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU MBIGA1UECwwLU1NPUHJvdmlkZXIxFTATBgNVBAMMDGRldi0wMjg4NzY4NjEcMBoGCSqGSIb3DQEJ ARYNaW5mb0Bva3RhLmNvbTAeFw0yMTEyMDcxNTM5NTBaFw0zMTEyMDcxNTQwNTBaMIGUMQswCQYD VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsG A1UECgwET2t0YTEUMBIGA1UECwwLU1NPUHJvdmlkZXIxFTATBgNVBAMMDGRldi0wMjg4NzY4NjEc MBoGCSqGSIb3DQEJARYNaW5mb0Bva3RhLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC ggEBAIY6Ek4yvOB3pF4+IwAgVYyxdwOXi4AoorFUmgJ1Sv8kLc6SSApwIEKj2N/F8tYDxZKEGcV7 jap8gdYZcLpm4rKfNGw0jjQ+mCT4fcUdzLTsXQ1vzTy+KILvi1Ki3cgzEKt+Oir106XKDCgp+BGc PgGKRQQroxqrUWX12yEGyZ4D7pLt5Pg4SBC9o1xRfP+hK82ev1eO+hmp39pl6QDKPG0tV6FJI/SX bnchBNpGxT2qcMO8LzudQBS9fT7Nu0WPJGRRF/zQdB+ScHvBFnjlTKjEYPwM2yNx5FYMfcZM/qZH jyAocVdAR4LMEOi1jZwlPIgESIyCXYFVptoqm1U+Lh0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEA c8zc0J0p/oq8zHfVobh0QNov4NUS81iDl0ZcRC3LDJ50X360NPM3q7JRfwVMGGUWs0WNm+km0poa XYzWnZUYbRbeuvXB/lyCjUEVneF3quTpzifffVDO8sl1qosEOFlOPf1NOMiVMwRyBHqWRsbL96E1 TVBK7ezaIa/okXiPm0QflMHV9Sg1HyQHvAxo/topQI3FzrZRehrjol0K0vg29ZiV3Y32Ym2mAWD1 3fV7Fy8QcrbQpZseojkUqqfcIaCAOUtiK+oK86yDTkd6C6Ed5Ib0K7Ckwr0FdZ6w2wo4u+UIAnK+ IOOerfagyzpaT0lAPJ4G55sVX5min7plRDfqfA==</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>
<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat>
<md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://dev-02887686.okta.com/app/dev-02887686_testapp_1/abcdefghijklm/sso/saml"/>
<md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://dev-02887686.okta.com/app/dev-02887686_testapp_1/abcdefghijklm/sso/saml"/>
</md:IDPSSODescriptor>
</md:EntityDescriptor>
sp 侧配置
'service': {
'sp': {
'endpoints': {
'assertion_consumer_service': [
("http://example123.loca.lt/saml/sso/example-okta-com", BINDING_HTTP_POST),
("https://example123.loca.lt/saml/sso/example-okta-com", BINDING_HTTP_POST),
("http://example123.loca.lt/saml/sso/example-okta-com", BINDING_HTTP_REDIRECT),
("https://example123.loca.lt/saml/sso/example-okta-com", BINDING_HTTP_REDIRECT)
],
"single_logout_service": [
("http://example123.loca.lt/saml/slo/okta", BINDING_HTTP_REDIRECT),
("http://example123.loca.lt/saml/slo/okta", BINDING_HTTP_POST),
],
},
"required_attributes": ['displayName', 'mail', ],
"metadata_key_usage": "both",
"enc_cert": "use",
'allow_unsolicited': True,
'authn_requests_signed': False,
'logout_requests_signed': False,
'want_assertions_signed': True,
'want_response_signed': False,
},
},
"key_file": "./pki/mykey.pem",
"cert_file": "./pki/mycert.pem",
"xmlsec_binary": '/usr/bin/xmlsec1',
'encryption_keypairs': [
{
'key_file': "./pki/mykey.pem",
'cert_file': "./pki/mycert.pem",
},
],
okta中的设置
Single Sign On URL http://example123.loca.lt/saml/sso/example-okta-com
Recipient URL http://example123.loca.lt/saml/sso/example-okta-com
Destination URL http://example123.loca.lt/saml/sso/example-okta-com
Audience Restriction http://example123.loca.lt/saml/sso/example-okta-com
服务提供商 python fastapi 代码
metadata_url_for = {
# you can have multiple 'Application Integration' settings in okta and can use here for testing.
# key : value (metadata link for 'Application Integration' created in okta)
'app_integration': 'https://dev-02887686.okta.com/app/exk2zsnf574m2JD4w5d7/sso/saml/metadata'
#'app_integration': 'https://dev-02887686.okta.com/app/dev-02887686_testapp_1/exk2zsnf574m2JD4w5d7/sso/saml'
}
# get saml client configuration for a given idP name. Here SAML client means
# Service Provider.
def saml_client_for(idp_name=None):
'''
Given the name of an IdP, returns a saml configuration.
The configuration is a hash for use by saml2.config.Config
'''
if idp_name not in metadata_url_for:
raise Exception("Settings for IDP '{}' not found".format(idp_name))
rv = requests.get(metadata_url_for[idp_name]) # make http get request with given url and read its response in 'rv'
settings = {
'entityid': 'http://example123.loca.lt/saml/sso/example-okta-com',
'metadata': {
'inline': [rv.text],
},
'service': {
'sp': {
'endpoints': {
'assertion_consumer_service': [
("http://example123.loca.lt/saml/sso/example-okta-com", BINDING_HTTP_POST),
("https://example123.loca.lt/saml/sso/example-okta-com", BINDING_HTTP_POST)
],
"single_logout_service": [
("http://example123.loca.lt/saml/slo/okta", BINDING_HTTP_REDIRECT),
("http://example123.loca.lt/saml/slo/okta", BINDING_HTTP_POST),
],
},
"required_attributes": ['displayName', 'mail', ],
"metadata_key_usage": "both",
"enc_cert": "use",
'allow_unsolicited': True,
'authn_requests_signed': False,
'logout_requests_signed': False,
'want_assertions_signed': True,
'want_response_signed': False,
},
},
"key_file": "./pki/mykey.pem",
"cert_file": "./pki/mycert.pem",
"xmlsec_binary": '/usr/bin/xmlsec1',
'encryption_keypairs': [
{
'key_file': "./pki/mykey.pem",
'cert_file': "./pki/mycert.pem",
},
],
}
spConfig = Saml2Config()
spConfig.load(settings)
spConfig.allow_unknown_attributes = True
saml_client = Saml2Client(config=spConfig)
return saml_client
@app.post("/saml/sso/example-okta-com")
async def idp_initiated(request: Request):
print("In idp_initiated....\n")
key_str = 'app_integration'
saml_client = saml_client_for(key_str)
form = await request.form()
authn_response = saml_client.parse_authn_request_response(
form.get('SAMLResponse'),
entity.BINDING_HTTP_POST)
authn_response.get_identity()
user = User(authn_response.name_id, authn_response.ava, authn_response)
request.session["user_name_id"] = str(user.name_id)
user_store = {'first_name': authn_response.ava['displayName'][0], 'last_name': authn_response.ava['displayName'][0],
'user_name': authn_response.ava['cn'][0]}
# instead of responding with user data. We are redirecting it to home page.
# resp = JSONResponse(user_store)
resp = RedirectResponse("https://example123.com/home")
uid = rndstr(32)
uid2user[uid] = user
resp.set_cookie(key='spauthn', value=authn_response.name_id, httponly=True, expires=1800)
resp.status_code = 302
return resp
@app.get("/saml/login/example-okta-com")
def sp_initiated():
print("In sp_initiated....\n")
key_str = 'app_integration'
saml_client = saml_client_for(key_str)
reqid, info = saml_client.prepare_for_authenticate()
redirect_url = None
# Select the IdP URL to send the AuthN request to
for key, value in info['headers']:
if key == 'Location':
redirect_url = value
response = fastapi.responses.RedirectResponse(redirect_url)
response.headers['Cache-Control'] = 'no-cache, no-store'
response.headers['Pragma'] = 'no-cache'
return response
然后我降落到
您正在使用 idp 流的元数据。在 idp 流中,您不会以这种方式重定向到 SP。使用 Sp 流的元数据,其中应包含指向您的服务的重定向 url,以便 idp 可以重定向