我使用Spring Security
和pac4j-oauth
保护了RESTful服务。一个重要的细节是,Google充当OAuth2
服务器 - 我们需要用户的Gmail地址才能知道他们是否是我们系统的合法用户,并且最终该服务还需要访问他们的日历。
当用户首次访问受保护资源(输入URL)时,他们会被重定向到Google。一旦他们通过身份验证,他们就会被重定向回我们的服务。这很好。
问题是我想使用Ajax
来调用服务。当我发出第一个Ajax
电话时,它会重新定向到Google。这可能会扰乱Ajax
电话,但实际上它甚至都没有达到这个目的。浏览器会看到重定向并抛出CORS
错误:“请求资源上没有'Access-Control-Allow-Origin'标头。因此不允许原点'https://localhost:8443'访问。“
我不知道如何处理这个问题。建议是值得欢迎的。
一些想法:
如果我使用Ajax
调用替换常规JSONP
调用,重定向仍会导致错误(因为它返回的是URL而不是JSONP
脚本)但是客户可以检测到并代表该服务导航到Google?一旦用户进行身份验证,客户端就可以再次将它们带回受保护的资源吗?
但这感觉不对。首先,这意味着RESTful服务的未来Ajax
客户端必须跳过相同的环节。我希望客户端不要对服务器的安全实现有任何依赖。
虽然CORS
错误很常见,但我发现其他几个人在使用OAuth2
身份验证时特别抱怨这些错误。所以我也想知道我们的架构在某个地方是否采取了错误的转向。我们究竟在做什么这么不寻常?
任何见解都将受到赞赏。
答案 0 :(得分:1)
经过更多的调查,这是我的结论。
我先从#2开始。是的,我们可能走错了路。具体来说,OAuth2
是为授权设计的,而不是身份验证。 (虽然如果我们一直在运行我们自己的OAuth2
服务器,我们可能已经离开了它。)
Google支持当然的身份验证:请参阅Google Sign-In的文档。但请注意他们列出的两个选项。
RESTful
服务不起作用。 因此,我们的计划是,我们会有一个网页提供授权我们的服务访问其Google日历的选项。用户将明确点击该链接以获得Google的授权 - RESTful
服务无需重定向其浏览器。这可以避免CORS
问题。然后,客户端会将Google的访问令牌发布到我们的RESTful
服务。
请注意,我们服务的其他消费者不需要实现此功能,他们只需要让用户以不需要重定向到第三方的方式进行身份验证。最初我们将使用我们自己的用户/ pwd数据库,着眼于将来挂钩到公司目录或SSO
。 Spring Security
当然支持多种选择。
所以:我们不得不妥协我们原来的计划,但现在我们正在处理有详细记录并有示例代码的流程。所以我希望从现在开始事情会变得更顺畅。
我希望这可以帮助某人避免我们犯同样的OAuth2
设计错误,即将其与第三方一起使用来验证我们RESTful
服务的用户。有更合适的方法来验证用户。