简单 SSO - 使用自定义身份验证 - CAS 或一些 Oauth 或 openid 服务器?

Posted

技术标签:

【中文标题】简单 SSO - 使用自定义身份验证 - CAS 或一些 Oauth 或 openid 服务器?【英文标题】:Simple SSO - using custom authentication - CAS or some Oauth or openid server? 【发布时间】:2011-08-25 13:00:55 【问题描述】:

我想了解更多关于 不同的解决方法 登录及其优缺点。您是否使用过一种特定的解决方案,告诉我它有什么好处,并告诉我有哪些限制或次优部分。

下面 是我想要的细节 知道或不明白。

SSO 是一个巨大的话题,就像listed in the wikipedia。我学得越多,我的问题就越多。

首先我不明白CAS需要token验证,有什么用?

它更安全吗? 我猜它很容易受到中间人攻击。客户端也应该使用 ssl 吗?

让我们变得真实,这是我们的需要:如果已经登录我们的某个应用程序,则自动识别/登录用户。

my-php-app.com my-java-app.com my-ruby-app.com

(我们有许多 webapps,用不同的语言编写)

我们希望(保留)我们自己的身份验证规则和用户存储,但可能会添加一些 Oauth2 提供程序,如 facebook-connect。我们希望它对用户来说非常简单,对使用它的开发人员来说也很简单。

你会怎么做?

CAS? Openid?我可以使用它进行集中身份验证吗? 其他?还是使用 OAuth 的服务器?

在客户端,您会使用 iframe(如灯箱)来显示重定向页面吗?为什么/为什么不?


另一个与 SSO 相关的问题:Saml 经常(错误地?)混入 SSO 讨论 - 如果我这么说,我明白吗

saml 实现不会提供 sso(自动登录)当指向 浏览器访问 www.yetanother-myapp.com?


我研究过的一些相关的 SO 问题:

SSO with CAS or OAuth? - 他的需求描述不是我想要的,他描述的是 CAS... OpenID as a Single Sign On option? - 好吧,我不确定我从中学到了什么。

谢谢你教育我!

【问题讨论】:

我理解 OpenID 的方式是它提供去中心化的身份验证。从用户的角度来看,它允许集中身份管理。基本上,您信任身份提供者(OpenID 服务器)来对用户进行身份验证,而作为服务的您不需要那么关心身份验证。您可以对其进行配置,使其作为 SSO 工作,但我认为这不是它的重点。 很好的答案!我希望我能平分 250 赏金,但我不能。一定要查看@Hendrik Brummermanns 的答案,这对@paan 很有价值。为他们俩点赞,表达你的感激之情。 【参考方案1】:

Oauth 旨在对应用程序进行身份验证,让它们以用户的名义行事。例如,推特客户端可能会使用用户的帐户发布推文。它可以用于 Facebook 显示的单点登录,但这需要一些额外的工作。

比较 CAS 和 OpenID

CAS 是一个集中式系统,具有一个帐户权限。 OpenID 是一个分布式系统,基本上任何人都可以在其中设置身份提供者。当然你可以限制你的消费者只接受你自己的身份提供者。

OpenID 有两个(不兼容的)标准来提供关于帐户的附加属性,公共库或多或少地支持这些标准。在标准设置中,CAS 只提供用户名。虽然理论上 CAS 确实支持属性交换,但目前 only the PHP client supports it.

OpenID 和 CAS 都可以自动登录。如果用户已经登录,浏览器将立即重定向回您的应用程序。但是,在简单的设置中,如果用户未登录,身份提供者将显示一个登录页面。因此,如果您想允许匿名访问您的一方,这将需要人们单击专用的登录链接。

幸运的是,OpenID 和 CAS 都允许透明的登录尝试。在这种模式下,登录表单不显示。浏览器会在有或没有身份验证信息的情况下立即重定向回来。换句话说:您可以在所有新用户(没有会话)访问您的站点后立即将他们重定向到身份提供者。有一个nice diagram 详细解释了这一点。 CAS 称之为“网关模式”,它是通过将 gateway=true 附加到登录 URL 来实现的。在 OpenID 中称为“即时模式”,URL 参数为 openid.mode=checkid_immediate

CAS 支持单点注销。 OpenID 没有。

我的个人经验是,CAS 非常容易设置,并且非常可靠,它具有适用于所有常见编程语言的高质量库。 OpenID 有许多微小的不兼容性,因为它是一个复杂得多的系统。但是,OpenID 允许使用 Google 帐户。

答案

首先我不明白 CAS 需要令牌验证,有什么用?

OpenID 和 CAS 都要求您让身份提供商验证提供的令牌。否则,攻击者可能能够创建自己的令牌或使用用户在注销之前创建的令牌。

客户也应该使用 ssl 吗?

是的。

在客户端,您会使用 iframe(如灯箱)来显示重定向页面吗?为什么/为什么不?

一个完整的屏幕重定向是最简单的事情。我会从它开始让它工作。无论如何,许多应用程序都需要在登录后重新加载当前页面,以显示仅对登录用户可见的部分。

Iframe 存在登录完成后需要将其删除的问题。对于 CAS,有一个 tutorial 介绍如何将 CAS 登录表单直接嵌入到应用程序的 html 代码中。另一种选择是像 Facebook Connect 那样显示一个弹出窗口。

【讨论】:

很好的答案!为什么在客户端上使用 ssl?优点和缺点。这个人应该回答这个问题:***.com/questions/5279910/… :) @Ole Morten Amundsen,好的,我在那里更详细地介绍了。【参考方案2】:

我可以回答一些我以前使用过的关于 CAS 的问题。我没有使用 OAuth 的经验,因此不会对此发表评论。

首先我不明白 CAS 需要令牌验证,有什么用?

CAS 用于 SSO 目的。当您有多个想要从单一来源进行身份验证的应用程序(不同 TLD 上的桌面应用程序/网络应用程序)时使用它。

它更安全吗?我注意到它是基于重定向的,因此同样受到中间人攻击,就像没有额外令牌验证步骤的“自定义”身份验证服务器一样。我错过了 CAS 中的安全性吗?

身份验证服务器使用 SSL 来防止中间人攻击。但我看不出这是 SSO/CAS 所特有的问题,因为即使应用程序正在执行自己的身份验证,您也会遇到同样的问题。也许您可以告诉我们您担心 CAS 设置会发生什么样的中间人攻击

令牌的目的是提供单点注销和/或超时吗? (我们不想要它,我们的用户会讨厌我们。)我一直在研究 CAS,因为有一些很棒的 Ruby 实现,但我不确定它是否是我们需要的。

令牌只是应用程序无需密码即可对您进行身份验证的一种方式。它们是与您的用户凭据相关联的短寿命/一次性使用的令牌。应用程序将令牌提供给 CAS 服务器,并且 CAS 服务器回复一个凭证(如果有与之关联的凭证)。可以实现单点注销和超时,但与拥有令牌没有直接关系。

我希望这很清楚。我试图让它成为一个高级别的解释。如果有任何不清楚的部分或您想了解更多细节,请随时询问细节。

编辑:我在http://www.jasig.org/cas/proxy-authentication 找到了关于 CAS 工作原理的更好的简单解释(页面的其余部分讨论代理身份验证。这更复杂,但前几段是我们在这里讨论的简单案例)

我转到我的 Portal 实例。它会将我重定向到 CAS 登录。 CAS 检测到我的安全 cookie 并执行单点登录,因此我不必再次提供我的用户名和密码。 CAS 将我重定向回门户。门户验证票证,将我登录到门户 我看到我的默认布局填充了一些很酷的频道,告诉我外面真的很冷以及新闻中的什么。

请注意,门户没有获得我的密码。

【讨论】:

感谢 paan,但您并没有真正回答 为什么使用令牌,而是解释了 what。我会尝试改写。 “为什么不首先返回凭据?(而不是令牌)?”。 令牌被提供给用户,而用户又将其提供给想要对用户进行身份验证的应用程序。然后应用程序从 CAS 服务器请求凭证。将凭据提供给用户,然后将其传递给应用程序将使身份验证毫无意义,因为用户随后将能够提供他想要的任何凭据。 你刚才说的,没有意义,用户不处理令牌...用户进入my-app.com,被重定向到my-auth.com,用户认证.到目前为止一切顺利,对吧? CAS 和非令牌解决方案相同。那么接下来,为什么用 token 重定向回 my-app.com 而不是直接用 userid 响应呢? 当用户被重定向到 my-app.com 并且令牌将作为标头请求传回。所以你实际上会被重定向到(例如)my-app.com?ticket=ST-956-Lyg0BdLkgdrBO9W17bXS。然后应用程序将获取该令牌并(通过其自己的通道到 CAS 服务器)将其提供给 CAS 服务器,CAS 服务器将返回与该令牌关联的凭证。应用程序将令牌带到 CAS 服务器的额外步骤是必要的,因为否则没有什么能阻止用户每次只说“我是 root”。 再次感谢。关键是“在安全通道上验证”。正如我从 CAS 协议规范(我最近读过很多书,但现在用不同的眼光)看到的那样,jasig.org/cas/protocol(第 2.1.3 节)它是一个 http POST,而不是重定向 (GET)。如果 my-app.com?userid=1,我明白您的观点,即用户能够操纵 URL。感谢您的启发。【参考方案3】:

这是基于我的经验: SSO(单点登录)与两种情况有关:- i) 我很了解你(涉及两方) ii) 嘿朋友,见见我的朋友(涉及三方)

当然,第二种情况需要重定向/转发机制,因为通常第三方只是集中的身份验证/授权服务。

现在,在实施方面,SSO 需要评估两个方面:-

a) 不同方/系统(无论是相关组织的内部/外部)如何管理用户凭据。这称为身份管理。

b) SSO 信息应如何在各方之间流动?在大多数情况下都是安全的。

我认为身份管理比确定如何安全地传递信息更重要,因为在后半部分有很多可用的加密/解密技术。在一组启用了 SSO 的系统中,它是完全不同的不安全管理。

现在身份管理可以通过简单的用户 ID(如果它在所有参与系统上可用)、内部开发的 XML 内容、SAML 有效负载或第三方令牌来实现。我认为令牌只是一个通用术语,指的是容器以安全的方式包含用户凭据以及有关执行的某些安全程序的信息。

@Ole,上面说了所有关于 SSO 的基础知识(从我的角度来看),我认为您应该更多地关注如何在多个系统中识别用户及其角色,即在您的情况下:- 您的用户存储,打开 outh2 提供程序;因此,请多考虑身份管理。

一种解决方案可能是(取决于您的预算和时间),您的企业可以花费精力以标准集成技术的形式创建内部集中式身份验证界面,例如Web 服务和这些 API 背后,您可以有任何实现:您自己的提供者或第三方 oAuth 或两者的混合。您可以在您的 API 和作为决策者的提供者层之间实现一个引擎层。例如引擎可以具有应用程序域和相应的身份验证提供程序映射。 这样,您将为其所有客户端拥有统一的身份验证接口。

客户端 --> 内部集中式 API --> 引擎 --> 身份验证提供者 让我举个例子:- i) 你可以有一个 Webservice 暴露,命名可能是 singleSigonService。 XML 有效负载可能类似于:-

<SingleSignOnReqType>   <sourceID>XYZ</sourceID>    <source-domain>my-java-app.com</source-domain>  <user-credentials>...</<user-credentials>
        <security-credentials>...</<security-credentials> </SingleSignOnReqType>

ii) Web 服务客户端将对集中式引擎层进行 SSO 调用(以任何技术实现),该层可以进行验证和记账,并且可以基于源域(例如 my-java-app.com)在传入的 XML 中,会将请求委托给 Oauth2 提供者,例如 facebook-connect。因此,您的引擎(决策者)将按照您在要求中提到的那样管理身份验证规则。

所以基本上所有消费者应用程序都将有一个统一的基于 Web 服务的接口来连接您的 SSO 解决方案。这就是我所指的内部集中式 API。

【讨论】:

请在上面的答案中编辑此内容,只留下一个答案,并添加更多链接和示例。解释“在你的 API 和提供者层之间实现一个引擎层......”和内部集中式 API(你是说 CAS 吗?或用于身份管理的 api)。我希望你能更具体一些。 @oma: 字符限制是我需要写出逻辑上分开的 2 个 cmets 的主要原因......不要仅仅为了理解而拒绝你的投票......尽管如此,让我知道你有多远有关 SSO 的问题已得到解答,还有什么待解决的问题……最终,我目前正在为我当前的项目开发 SSO 解决方案……所以你的问题对我来说也很重要,以确保我没有遗漏任何东西…… 在我要求你这样做几天后,我一清理就删除了反对票和评论。

以上是关于简单 SSO - 使用自定义身份验证 - CAS 或一些 Oauth 或 openid 服务器?的主要内容,如果未能解决你的问题,请参考以下文章

具有自定义外部表单和弹簧安全性的 CAS 身份验证

具有 CAS 身份验证和自定义授权的 Spring Security

是否可以通过 SSO 将旧 CAS 3.5.3 服务器的身份验证传递到最近的 Keycloak 15.0.2?

多个应用程序上的 SSO 和 REST Api 身份验证

Spring OAuth2:支持 SSO 和自定义身份验证服务器的身份验证和资源访问

CAS SSO - 覆盖 LDAPHandler