为什么 okta 在 SSO 情况下不重定向回服务提供商

问题描述 投票:0回答:1

我正在使用开源项目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

然后我降落到

single-sign-on saml-2.0 fastapi okta
1个回答
0
投票

您正在使用 idp 流的元数据。在 idp 流中,您不会以这种方式重定向到 SP。使用 Sp 流的元数据,其中应包含指向您的服务的重定向 url,以便 idp 可以重定向

© www.soinside.com 2019 - 2024. All rights reserved.