如何为特定操作创建ssl连接,但仍允许http用于所有其他站点操作?

时间:2014-02-26 16:50:23

标签: javascript angularjs twitter-bootstrap ssl asp.net-web-api

我已经为这个问题的解决方案工作了大约一个星期,但我陷入了僵局。我已经搜索了许多在线资源,但还没有找到相关的例子。根据我在互联网上阅读的内容,这种类型的操作应该是可行的。但是,我之前没有尝试过这种性质的东西,所以我的方法可能会有一些明显的误解/错误。

以下系统配置是否可以使用此操作模式?如果是这样,请伸出援助之手。

以下是一些相关信息。

系统配置:具有许多部分视图的单页应用程序(一些需要ssl,大多数不需要)

  1. 客户端:使用最新版本的AngularJS,Bootstrap和TypeScript,以及CSS,HTML5
  2. 服务器:使用IIS 7和C#Web API 2.0
  3. ...谢谢

    单页应用程序要求:

    1. 针对智能手机,平板电脑,笔记本电脑和个人电脑的所有主要操作系统。
    2. 需要为所有会员注册,登录和一些数据创建操作进行安全通信。
    3. 对于所有与用户无关的下载,需要非安全的http。这相当于每天总站点使用量的99%。
    4. 背景:

      1. 如果我使用https运行应用程序,该网站可以正常工作。
      2. 如果我在Web API控制器中禁用RequireHttps属性,则该网站可以正常工作。
      3. 我尝试过启用CORS无济于事。
      4. 我不明白为什么Fiddler显示200返回值,但我的应用显示404错误。
      5. Fiddler结果:

        HTTP隧道到www.myDomain.com:443

        HTTPS www.myDomain.com / api /身份验证/登录?memberInfo = df ... xs

        1. 使用IE11,Chrome和Safari,Fiddler的上述结果均为200。
          • 这些浏览器可以正确访问服务器Web API。
          • Web API登录方法返回正确的加密字符串值。
        2. Firefox在Fiddler for Tunnel中返回200,但不像其他浏览器那样执行HTTPS调用。
        3. 在我的应用程序中,当使用RequireHttps属性注释时,回调会返回404错误。
        4. 相关守则:

          this.http({
          method: 'POST',
          url: 'https://www.myDomain.com/api/Authentication/' + "Login?memberInfo=" + $scope.base64Service.encode(memberInfo),
          }).
          success(function (data, status, headers, config) {
            // Success code here.
          }).
          error(function (data, status) {
            // error code here.
            // data = “” for https with status = 404;
          });
          
          public class AuthenticationController : ApiController {
          [RequireHttps]
          [HttpPost]
          public string Login(string memberInfo) {
              // login code here.
              return memberData;
              }
          }
          
          public class RequireHttpsAttribute : AuthorizationFilterAttribute {
          public override void OnAuthorization(HttpActionContext actionContext) {
              if (actionContext.Request.RequestUri.Scheme != Uri.UriSchemeHttps) {
                 actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Forbidden) {
                    ReasonPhrase = "HTTPS Required"
                 };
              }
              else {
                  base.OnAuthorization(actionContext);
              }
            }
          }
          

          CORS的web.config文件条目

          已修改,已移除第二个域

          <httpProtocol>
              <customHeaders>
                  <add name="Access-Control-Allow-Origin"
             value="http://myDomain.com" />
              </customHeaders>
          </httpProtocol>
          

          修改

          使用一个域作为Access-Control-Allow-Origin和AngularJS的以下代码,我已经能够在所有浏览器中获得安全的隧道连接。我还必须将我的测试服务器的自签名证书添加到Firefox的域例外列表中。这解释了我测试的四种浏览器之间的差异。显然,浏览器都不允许请求,因此404错误。即使服务器返回成功的响应,浏览器也没有将响应提供给我的客户端应用程序。

          smmApp.config(['$httpProvider', function ($httpProvider) {
          $httpProvider.defaults.useXDomain = true;
          delete $httpProvider.defaults.headers.common['X-Requested-With'];
          }
          ]);
          

2 个答案:

答案 0 :(得分:0)

您需要在Access-Control-Allow-Origin

中指定单个域

答案 1 :(得分:0)

您似乎正在尝试使用SSL来防御中间人攻击。如果是这种情况,则无法按照您的描述进行操作。

如果通过HTTP发出对页面的请求并且发生了MitM攻击,则没有任何东西阻止攻击者改变向浏览器提供的javascript,以便通过恶意服务器代理凭据请求。

这就是为什么确保您的登录表单及其发布的页面都通过SSL提供的重要性。

我保证,这不是理论上的。如果您想要使用SSL,则必须通过SSL提供整个站点。

您看到的错误似乎是一个CORS问题。