ВАРИАНТЫ предполётного запроса на получение 400 неверных запросов по https - PullRequest
0 голосов
/ 16 мая 2019

У меня есть вызов Ajax на внешнем интерфейсе, и я вызываю службу WCF через вызов ajax, но вызов ajax имеет несколько добавляемых заголовков, поэтому первый запрос preflight OPTIONS поднимается, и его падение из-за "url" было заблокировано политикой cors.

Я добавил код ниже в моем файле web.config, но он все еще работает.

<system.webServer>
        <security>
            <requestFiltering>
                <verbs>
                    <add verb="OPTIONS" allowed="true" />
                    <add verb="POST" allowed="true" />
                    <add verb="GET" allowed="true" />
                    <add verb="DELETE" allowed="false" />
                </verbs>
            </requestFiltering>
        </security>
        <httpProtocol>
            <customHeaders>
                <remove name="X-Powered-By" />
                <add name="Access-Control-Allow-Credentials" value="true" />
                <add name="Access-Control-Allow-Origin" value="*" />
                <add name="Access-Control-Allow-Methods" value="GET,POST,DELETE,OPTIONS" />
                <add name="Access-Control-Allow-Headers" value="accept, cache-control, content-type, authorization, context" />
            </customHeaders>
        </httpProtocol>
    </system.webServer>


$.ajax({
                async: true,
                type: "POST",
                headers: {
                    'Authorization': 'Basic ' + btoa(BasicAuth),
                    'Context': 'Context' + btoa(ContextHeader)
                },
                contentType: "application/json; charset=utf-8",
                data: '{"Id": "' + Id + '" }',
                url: URL + "/MethodName",
                success: function (result) {
                    response = result;
                    if (response == true)
                        Xrm.Page.data.refresh(true);
                    $('#msgDiv').fadeOut('slow');
                },
                error: function (status) {
                    console.log(status.status);
                    $('#msgDiv').fadeOut('slow');
                    Configurations.OnFailure(status);
                }
            });

Выше кода, который я написал на JavaScript.

При вызове HTTP он работает нормально.Но при вызове HTTPS он не работает.

Я получаю сообщение об ошибке, как показано ниже на консоли

enter code here
  • ОПЦИИ https://abc/xyz 400 (неверный запрос)

  • Доступ к XMLHttpRequest в «https://abc/xyz от источника» https://Localhost' заблокирован политикой CORS: Ответ на предпечатный запрос не проходит проверку контроля доступа: У него нет статуса HTTP ok

Ответы [ 2 ]

0 голосов
/ 16 мая 2019

Вот мое решение CORS, если оно вам пригодится.Добавьте класс глобального приложения в мое приложение-службу wcf.
Global.asax

protected void Application_BeginRequest(object sender, EventArgs e)
        {
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
            if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
            {
                HttpContext.Current.Response.AddHeader("Cache-Control", "no-cache");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With,Accept");
                HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
                HttpContext.Current.Response.End();
            }
        }

Файл web.config на сервере

  <system.serviceModel>
    <bindings>
      <webHttpBinding>
        <binding name="mybinding">
          <security mode="Transport">
            <transport clientCredentialType="Basic" proxyCredentialType="Basic"></transport>
          </security>
        </binding>
      </webHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
          <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior>
          <webHttp />
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true">
    </serviceHostingEnvironment>
    <protocolMapping>
      <add scheme="https" binding="webHttpBinding" bindingConfiguration="mybinding"/>
      <add scheme="http" binding="webHttpBinding" />
    </protocolMapping>
  </system.serviceModel>

Затем установите сертификат службы сервера на клиенте (где мы запускаем JS).
enter image description here
JS.

<script>
        function make_base_auth(user, password) {
            var tok = user + ':' + password;
            var hash = window.btoa(tok); //javascript built-in function
            return "Basic " + hash;
        }
        $(function () {
            $.ajax({
                type: "GET",
                url: "https://vabqia130vm:12001/service1.svc/getdata?value=34",
                contentType: "application/json;charset=utf-8",
                beforeSend: function (req) {
                    req.setRequestHeader("Authorization", make_base_auth("administrator",
                        "abcde12345!"));
                },
                success: function (d) {
                    console.log(d);
                },

            });

        })
    </script>

Результат.
enter image description here
Не стесняйтесь, дайте мне знать, если есть что-то, с чем я могу помочь.

0 голосов
/ 16 мая 2019

Я создал dispatchmessageInspector на стороне службы для проверки правильности проверки подлинности перед вызовом фактической службы.

Ниже код, который я написал для обработки аутентификации на диспетчере диспетчера.

public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
        {
            var logFileName = SetLogInfo("JavaScriptBasicAuth");
            try
            {
                if (!HttpContext.Current.Request.HttpMethod.Equals("OPTIONS"))
                {
                    var basicAuth = HttpContext.Current.Request.Headers["Authorization"];
                    if (basicAuth != null)
                    {
                        string[] separator = basicAuth.Split(' ');
                        BasicAuthenticationBehaviorAttribute basicauth = new BasicAuthenticationBehaviorAttribute();
                        if (!basicauth.ValidateBasicAuth(separator[1]))
                        {
                            throw new WebFaultException(HttpStatusCode.Unauthorized);
                        }
                    }
                    else
                    {
                        FileLogger.LogError("401 (Unauthorized) Error - " + "You are not authorized to perform this operation. Please contact administrator.", LOG_SUB_DIRECTORY, logFileName);
                        throw new WebFaultException(HttpStatusCode.Unauthorized);
                    }
            }
        }

Но вызов не выполняется до кода инспектора диспетчера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...