使用 CORS 实现 SSO 是否安全?

信息安全 sso 科尔斯
2021-08-22 04:07:52

我实现了 SSO 以将一些 Web 登录机制集成到作为 OAuth2 提供者的集中式成员系统中。目前 OAuth2 授权运行良好。

但是,我想通过 AJAX 调用实现更流畅的登录方法。例如,用户已经登录了 web A 和会员系统。当用户导航到 web B 时,web B 应该调用 AJAX 到成员系统来查看用户是否登录?如果用户登录,web B 应该向用户显示登录页面。

我研究了一些 OAuth2 文章(我现在找不到链接)。他们都通过直接重定向到 OAuth 提供者来执行 SSO。但是,我想使用 CORS AJAX 调用,因为它可以提供更好的用户体验。

我阅读了另一个关于 CORS 和 SSO 风险的讨论:Designing single-sign-on with JSONP/CORS?

但我无法理解所选的答案。

必须有适当的控制措施来防止恶意 JavaScript 客户端伪造与授权服务器的交互。如果 URL 作为 CORS Ajax 请求中的参数提供,而不是检查 HTTP 原始标头,则允许恶意客户端对其上下文撒谎。

该 URL 可以通过 CORS 标头 Origin 进行验证。

我的看法是,如果 OAuth2 Provider 正确设置了 CORS Origin,那么支持 CORS AJAX 登录机制应该没问题。因为cookie和CORS不能跨域访问,违反了CORS Origin策略,所以不会受到CSRF攻击。只需要担心 XSS。

我对自己的意见不是很自信,这就是我在这里发帖的原因。如果您有任何建议或发现我的错误,请告诉我。

[更新更多细节]
在会员系统中,我会像这样定义 CORS 设置

app.use(cors({
   origin: ["http://weba.com", "http://webb.com"],
   credentials: true,
   methods: ['GET', 'POST']
}))

app.get('/sniff', (req, res)=>{
    if(req.session.user){ res.send("user login")}
    else res.send("not login yet")
}) 

在 webA 中,

xhr.withCredential = true
xhr.open("GET","http://member.com/sniff") => I can tell if user login or not.
1个回答

除了只需要处理一个用户数据库的优势之外,使用 SSO 还有两个重要的安全优势:

1) 应用程序不应该看到凭据 - 从而消除了一些攻击面

2) 由于浏览器重定向到 SSO 站点,用户可以轻松验证他们是否在适当的控制(TLS、HSTS)下向适当的系统提供密码。

您的提议似乎直接破坏了 2,并且由于应用程序会将客户端指向 SSO,因此您的提议间接破坏了第一个好处。