Вопрос

Вызов REST сервиса BPM Online из клиентского приложения

Добрый день!

Реализовал простейший Wcf сервис в BPM Online. Прописал все конфиги, по ссылке стало доступно описание сервиса http://localhost:89/0/ServiceModel/NewWebService.svc.



Создал консольное клиентское приложение, привожу код ниже. Получаю данные авторизации CookieContainer согласно примеру на академии. А вот дальше в ответ на запрос получаю ошибку: Удаленный сервер возвратил ошибку:403 запрещено. При этом аналогичный сервис размещенный в IIS работает корректно. Подскажите, как можно решить проблему.

Console.WriteLine("Успешна ли аутентификация?: {0}", TryLogin("Supervisor", "Supervisor"));

                string uri = "http://localhost:89/0/ServiceModel/NewWebService.svc/getCurrencyList";

                var currencyRequest = new NewWebService.request();

                currencyRequest.Id = "22";

                currencyRequest.operation = "getCurrencyList";

                currencyRequest.getCurrencyListParameters = new List();

                XmlSerializer serializer = new XmlSerializer(typeof(NewWebService.request));



                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);

                request.CookieContainer = AuthCookie;

                //request.KeepAlive = true;

                request.Method = "POST";

                request.ContentType = "text/xml";

                using (Stream requestStream = request.GetRequestStream())

                {

                    serializer.Serialize(requestStream, currencyRequest);

                }

                HttpWebResponse response = (HttpWebResponse)request.GetResponse();

                using (Stream responseStream = response.GetResponseStream())

                {

                    var responseStr = new StreamReader(responseStream).ReadToEnd();

                    responseStr = HttpUtility.HtmlDecode(responseStr);

                    XmlSerializer deserializer = new XmlSerializer(typeof(CurrencyServiceResponse.Response));

                    using (TextReader reader = new StringReader(responseStr))

                    {

                        var responseObj = (CurrencyServiceResponse.Response)deserializer.Deserialize(reader);

                    }

                }               

                response.Close();

Нравится

10 комментариев

Добрый день, Дмитрий!

Система может возвращать 403 на POST запросы в случае есть в Web.config включен UseCsrfToken

 <add key="UseCsrfToken" value="true" />

Тогда хедер http запроса должен выглядеть следующим образом:

Если это локальная разработка, и нет необходимости в csrf-защите, то можно отключить UseCsrfToken. (https://academy.terrasoft.ru/documents/technic-sdk/7-11/zashchita-ot-cs…)

Добрый день! Отключил в конфиге UseCsrfToken и теперь по ссылке http://localhost:89/0/ServiceModel/NewWebService.svc в браузере отображается ошибка: Сайт localhost выполнил переадресацию слишком много раз. Вернул конфиг на исходное значение, ошибка сохранилась.

Теперь сервис вновь доступен, запрос из клиента возвращает 400. Csfr отключен.



При запросе из fiddler вовращает 302.

a6

<html><head><title>Object moved</title></head><body>

<h2>Object moved to <a href="/0/ServiceModel/NewWebService.svc/getCurrencyList">here</a>.</h2>

</body></html>

 

 

Ошибка 400 - это Bad Request. У вас что-то не так с вызовом. Без описания сервиса и его метода сложно судить. Попробуйте создать отдельно WCF Service Application с вашим сервисом и потестируйте на нем

Через WCF Service Application развернутый в IIS работает. Описание сервиса и методов ниже.

//[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]

public class NewWebService : INewWebService

    {

        public ResponseData Auth(RequestData RequestData)

        {

            var data = RequestData.details.Split('|');

            var response = new ResponseData

            {

                Name = data[0],

                Age = data[1],

                Exp = data[2],

                Technology = data[3]

            };

            return response;

        }

        public response GetCurrencyList()

        {

            var resp = new response();

            resp.value = "<getCurrencyList><CurrencyList><externalId>EUR</externalId><isoCode>978</isoCode><isoTxt>EUR</isoTxt><cb>571.25</cb><sell>580</sell><buy>568</buy><CshSell>580</CshSell><CshBuy>568</CshBuy><CshBuyTrf>568.5</CshBuyTrf><name><translation lang=\"ru\" value=\"ЕВРО\" /><translation lang=\"en\" value=\"\" /><translation lang=\"am\" value=\"ԵՎՐՈ\" /></name><country /></CurrencyList><CurrencyList><externalId>RUR</externalId><isoCode>643</isoCode><isoTxt>RUR</isoTxt><cb>8.31</cb><sell>8.4</sell><buy>8.18</buy><CshSell>8.4</CshSell><CshBuy>8.18</CshBuy><CshBuyTrf>8.23</CshBuyTrf><name><translation lang=\"ru\" value=\"Российский рубль\" /><translation lang=\"en\" value=\"Russian ruble\" /><translation lang=\"am\" value=\"Ռուսական ռուբլի\" /></name><country>RUS</country></CurrencyList><CurrencyList><externalId>USD</externalId><isoCode>840</isoCode><isoTxt>USD</isoTxt><cb>478.39</cb><sell>480</sell><buy>477</buy><CshSell>480</CshSell><CshBuy>477</CshBuy><CshBuyTrf>477.5</CshBuyTrf><name><translation lang=\"ru\" value=\"Доллар США\" /><translation lang=\"en\" value=\"US dollar\" /><translation lang=\"am\" value=\"ԱՄՆ դոլար\" /></name><country>USA</country></CurrencyList><errorCode>0</errorCode></getCurrencyList>";

            return resp;

        }

    }

    [ServiceContract]

    [XmlSerializerFormat]

    public interface INewWebService

    {

        [OperationContract]

        [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml, UriTemplate = "auth")]

        ResponseData Auth(RequestData rData);

        [OperationContract]

        [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml, UriTemplate = "getCurrencyList")]

        response GetCurrencyList();

    }

}

Артем Гура,

Плюс при переходе в браузере по ссылке на сервис размещенный в IIS открывается страница Запрещенный метод, а на сервис размещенный в BpmOnline Http Error 400.

Тетиков Дмитрий Владимирович,

Разница между сервисом в IIS и в bpmonline в том что bpmonline необходимо пройти авторизацию и отправлять дополнительные токены и куки в хедере запроса.

Тут можно посмотреть примеры отправки запросов из Fiddler: https://academy.terrasoft.ua/documents/technic-sdk/7-11/vypolnenie-zapr…;

По аналогии вы можете отправлять запросы на NewWebService.svc

Еще раз хочу обратить внимание на хедер запроса: 

 

Проблема была в неверном конфиге. 

<service behaviorConfiguration="BaseServiceBehavior" name="CurrencyService.NewWebService">

При объявлении сервиса в аттрибуте name прописал название интерфейса, а не класса - сервиса.

Спасибо за рекомендации, теперь все работает корректно.

Tsopa,

В продолжение темы, подскажите пожалуйста, как сформировать запрос с Basic авторизацией. 

Отправляю в таком виде:

POST http://localhost:89/0/ServiceModel/NewWebService.svc/auth HTTP/1.1

Accept: text/xml

Content-Type: text/xml

Authorization: Basic U3VwZXJ2aXNvcjpTdXBlcnZpc29y 

Host: localhost:89

Content-Length: 191

<?xml version="1.0"?>

<RequestData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

  <details>Ivan|29|3years|C#</details>

</RequestData>



Получаю вот такой ответ:

 

HTTP/1.1 302 Found

Cache-Control: private

Transfer-Encoding: chunked

Content-Type: text/html; charset=utf-8

Location: /0/ServiceModel/NewWebService.svc/auth

Server: Microsoft-IIS/10.0

X-AspNet-Version: 4.0.30319

Set-Cookie: BPMSESSIONID=j22z5jiyd4njspgjq0tc32d0; path=/0; HttpOnly

Set-Cookie: .ASPXAUTH=; expires=Mon, 11-Oct-1999 19:00:00 GMT; path=/; HttpOnly

X-Powered-By: ASP.NET

X-Frame-Options: SAMEORIGIN

Date: Tue, 30 Jan 2018 09:06:22 GMT

9b

<html><head><title>Object moved</title></head><body>

<h2>Object moved to <a href="/0/ServiceModel/NewWebService.svc/auth">here</a>.</h2>

</body></html>

0

 

Тетиков Дмитрий Владимирович,

Используя Basic аутентификацию можно обратиться только к EntityDataservice.svc. Для всех остальных внешних запросов рекомендуется использовать AuthService.svc и соответствующие Cookie.

Больше информации можно получить тут: https://academy.terrasoft.ru/documents/technic-sdk/7-11/autentifikaciya…

Показать все комментарии