【发布时间】:2014-05-07 22:40:52
【问题描述】:
我正在尝试为具有一些通用功能的移动和常规网站开发 WEB API,其中之一是身份验证服务。我采用 VS2013 SPA 模板的服务器端部分并尝试基于个人帐户实现安全性。主要要求是能够使用用户名/密码登录并通过 facebook 登录。当 OWIN 中间件和客户端在同一个项目中(例如 VS2013 SPA 的示例)时,VS2013 的 Tempate 工作正常,但是当它不存在时,应该进行一些修改,我想分享:
- 应在用作 OWIN 中间件 CORS 的 WEB API 上启用。
- 在 UI 客户端(它是单独的项目/解决方案)中,应为每个 AJAX 请求添加额外的标头“X-Requested-With”:“XMLHttpRequest”。我注意到,如果没有它,WEB API 返回 XML 而不是 JSON 有效负载,这会导致 UI 示例中的映射不正确(failJSON 无法解析错误消息)。
- VS2013 SPA模板中的UI示例设置为与同一主机一起使用,因此应为UI客户端中的每个请求添加一些带有base url(WEB API url)的前缀。
因此,我通过实现自定义 UserManager、UserStore、IIdentityValidator 和 IPasswordHasher 成功扩展了解决方案,它们与我现有的 MongoDB 数据库和自定义逻辑一起使用。用户名/密码验证工作得很好——我从 WEB API 接收不记名令牌,并可以在后续调用中使用它。但我在外部身份验证方面遇到的主要问题是:在我的情况下是 facebook。实际上,所有外部登录流程都很顺利,并预测到最后一步:
授权端点检查外部登录 cookie 主体并找到关联的应用程序用户,然后将用户作为 Bearer 身份验证类型登录到授权服务器中间件。由于授权服务器看到请求参数 response_type 是令牌(在步骤 1 中),它将触发隐式流程,这将创建访问令牌并将其作为 URL 片段附加到 redirect_uri(步骤 1)。例如:
HTTP/1.1 302 找到 缓存控制:无缓存 Pragma:无缓存 过期:-1 位置:/#access_token=asd2342SDIUKJdsfjk3234&token_type=bearer&expires_in=1200&state=06hwltIjvnTn44hc 设置 Cookie:.AspNet.External=;路径=/; expires=周四,1970 年 1 月 1 日 00:00:00 GMT 设置 Cookie:.AspNet.Cookies=WJgdyZQs9N8TG20EWnik-j0;路径=/; HttpOnly 内容长度:0
在这里你可以看到/#access_token,它是为WEB API主机生成的,完整的url如下:
因此它不会重定向到发起身份验证的客户端(例如 [http://localhost:2108]),而是重定向到中间件主机本身(在我的情况下为http://mobileapi.example.loc:61707)。肯定会给出 404 Not Found,因为 WEB API 只包含服务器端并且无法解析这个#access_token - UI 客户端应该这样做。
所以我的问题是如何正确拦截重定向并将服务器主机替换为客户端主机?
附:我找到了构建这个#access_token 字符串的源代码。它在 OAuthAuthorizationServerHandler 类的 ApplyResponseGrantAsync 方法中,该实例是从 OAuthAuthorizationServerMiddleware 创建的。它具有内部可访问性。所以为了改变这种行为,我应该重写整个中间件,我认为这不是很好的方法。
附言我看到的另一个选项是在 WEB API 上创建全局处理程序,它拦截所有传入的请求,如果它找到一个从 #access_token 开始的请求,那么它将从请求中获取引用主机并重定向到它。但是很丑。
提前感谢。
【问题讨论】:
标签: asp.net-web-api owin asp.net-web-api2 katana