如何为多租户应用程序(具有不同的域名)的所有租户设置一个SAML应用程序



应用程序架构:

  • 我们有一个多租户设置,每个租户都有自己的URL
  • 每个租户都有自己的模式和配置

问题:

我们需要一个可以与所有租户集成的SAML应用程序。

租户URL示例:tenant1.myapp.com、tenant2.myapp.com和tenant3.myapp.com等

我们希望所有租户都与一个SAML应用程序集成,以验证这些租户中的用户。

|---------------- SAML App -----------------|
|                     |                     |
|                     |                     |
|                     |                     |
Tenant 1              Tenant 2              Tenant 3
(tenant1.myapp.com)   (tenant2.myapp.com)   (tenant3.myapp.com)

通常,我们可以为不同的租户提供不同的SAML应用程序,但这导致我们需要维护大量SAML应用,我们希望避免这种情况。

我们正在尝试一些解决方案。如果任何解决方案有效,我们将在此处更新答案。在此期间,如果有人有任何建议,请帮忙。

我们已经找到了这个问题的解决方案。在重定向到IdP登录页面期间,我们在请求中发送租户URL作为RelayState参数,该参数在从IdP到我们的SP的SAML断言请求体中返回给我们。

  • 我们编写了一个AWS Lambda(以及API网关(,以将SAML断言请求重新路由到所需的租户
  • 我们使用这个RelayState参数来知道这个请求来自哪个租户
  • 我们在SAML应用程序中将指向lambda(SSO路由器(的API网关URL配置为ACS URL

Lambda的功能:它从SAML断言请求主体中选择RelayState参数,并将请求重定向到所需的租户URL(存在于RelayState中(。

Login to the App(any Tenant) ==> Redirection to Login Page ==> (On successful login) Redirected to Lambda(SSO Router) ==> Redirected to the tenant URL(present in the RelayState)

我们用Python编写了Lambda。这是示例代码:

def lambda_handler(event, context):
body = event.get('body')
redirect_host = body.split('RelayState=https%3A%2F%2F')[1].split('%2')[0]
# Here the request body is urlencoded and the URL will be of the form https://tenant1.myapp.com/ - we are only picking tenant1.myapp.com from the RelayState
redirect_url = 'https://' + redirect_host + '/saml/?acs'
# Our SAML redirection URL is of the form https://tenant1.myapp.com/saml/?acs
logger.info(f"Redirecting To: {redirect_url}")
return {
'statusCode': 307, # Status code 307 is to preserve the method by which this URL was called. Using 302 changes the method to GET whereas the SAML request comes as a POST
'headers': {
'Location': redirect_url,
'Content-Type': 'application/x-www-form-urlencoded',
'Access-Control-Allow-Origin': '*',
},
'body': body,
}

最新更新