Доступ к веб-сервису через Https

  • Автор темы nvyush
  • Дата начала
N

nvyush

Здравствуйте все!
Может вопрос глупый, но ответа на форуме не нашёл. Нужно из стороннего клиента (не Лотус) вызвать веб-сервис на сервере Домино. Если подключаться из браузера, выводится форма запроса логина/пароля. Когда делаю пост-запрос из клиента в ответ получаю текст html этой самой формы авторизации. Как передать логин/пароль и вызвать submit этой формы? Под веб ничего ранее писать не приходилось.
 
K

Klido

Вызов вэб-сервиса - это не логин+пароль+сабмит.... Логин и пароль будут внутри кода, который обратиться к сервису, никакой формы не будет... Сами вэб-сервисы и их вызовы - отдельная большая тема, см вот и там внизу по линкам тоже...
 
T

turumbay

Здравствуйте все!
Может вопрос глупый, но ответа на форуме не нашёл. Нужно из стороннего клиента (не Лотус) вызвать веб-сервис на сервере Домино. Если подключаться из браузера, выводится форма запроса логина/пароля. Когда делаю пост-запрос из клиента в ответ получаю текст html этой самой формы авторизации. Как передать логин/пароль и вызвать submit этой формы? Под веб ничего ранее писать не приходилось.
в случае сессионной аутентификации залогиница на domino можно примерно так: постим login, password, redirectTo( url сервиса ) на names.nsf?Login
в ответ получим контент требуемой страницы плюс печеньку(cookie) с идентификатором сессии. Эту печеньку можно использовать в последующих обращениях к domino.
как именно запостить данные на сервер - зависит от "стороннего клиента".
Если сторонний клиент - это браузер, то залогиница можно аяксом:
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">"ajax login to domino"</div></div><div class="sp-body"><div class="sp-content">
Код:
var loginURL = "/names.nsf?Login";
var webServiceURL = "path to web service";
var callback = {
success : function( response ){ alert( response );/*response - ответ web-сервиса*/},
failure: function( status , text ){ alert(text); }
}
var ajax = new SimpleAjaxHandler();
ajax.createXhrObject();
ajax.request('POST', loginURL , callback , "Username=login&Password=password&RedirectTo=" + webServiceURL);
код SimpleAjaxHandler я постил здесь: link removed
в случае авторизации аяксом - нужно помнить про cross-domain policy

то же можно делать java или что там доступно на стороне клиента
 
N

nvyush

Может я неясно выразился. В общем, вызывать из Домино сторонние веб-сервисы и обрабатывать результат я умею. Возникла обратная задача — написать в Домино веб-сервис для вызова сторонним клиентом. Создал базу, в ней простенький веб-сервис, дал анонимусу и дефолту права автора, но достучаться до сервиса напрямую не могу — сервер домино требует авторизации, выводит стандартную форму с логином/паролем. Каким образом сформировать пост-запрос, чтобы "пройти сквозь" эту форму к сервису я никак не пойму.
 
K

Klido

или вот - 3-й линк по гууглу :)
 
N

nvyush

turumbay
Во, есть люди, меня понимающие. Редирект как раз мне и был нужен. Только почему-то не могу заставить его работать из явы. В строку браузера вставляю "https://MyDominoServer/names.nsf?Login&Username=Vasya%20V%20Pupkin&Password=1234&RedirectTo=/IT/MyDB.nsf/MyService" — редирект нормально проходит без запроса логина/пароля. Вставляю ту же самую строку в ява код — опять получаю страницу авторизации. Кто подскажет, куда ещё копнуть?
 
T

turumbay

turumbay
Во, есть люди, меня понимающие. Редирект как раз мне и был нужен. Только почему-то не могу заставить его работать из явы. В строку браузера вставляю "https://MyDominoServer/names.nsf?Login&Username=Vasya%20V%20Pupkin&Password=1234&RedirectTo=/IT/MyDB.nsf/MyService" — редирект нормально проходит без запроса логина/пароля. Вставляю ту же самую строку в ява код — опять получаю страницу авторизации. Кто подскажет, куда ещё копнуть?
Я и подскажу:
в реальности происходит следующее
на ваш первый POST сервер пришлет примерно такой пакет:
HTTP/1.1 302 Found
Server: Lotus-Domino
Location: [тут адрес, который вы запросили]
Set-Cookie: DomAuthSessId=[тут печенька]; path=/
После этого нужно послать еще один запрос: GET на конечный адрес и добавить cookies в заголовок http.

Браузер автоматом отвечает на редирект( и вставляет cookie ), т.о. достаточно одного ajax - вызова. При ручном вызове эту операцию нужно проделать самостоятельно: получить 302-й ответ от сервера, распарсить заголовки, вытащить кукис, собрать новый пакет и отправить его.
Вы какой объект в java используете? Не URL.openStream() часом? Если да - то вроде можно выставить HttpURLConnection.setFollowRedirects ( лучше конечно HttpURLConnection.setInstanceFollowRedirects , см. javadoc ). Я вот тока не помню - допишет ли он cookie.
Для понимания происходящего рекомендую включить снифер и посмотреть что реально летает к серверу и обратно
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 985
611
BIT
473

ну и конечно же
 
N

nvyush

Использую HttpsURLConnection.getOutputStream(). Попробовал явно выставить
HttpsURLConnection.setFollowRedirects(true);
urlConn.setInstanceFollowRedirects(true); — безрезультатно. Попробую погрызть печеньки :). Смущает только заявление в справке по веб-сервисам, что поддерживаются только пост-запросы.
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 985
611
BIT
473
может на мысль натолкнёт :)
 
K

Klido

ещё на мысль
саму тестовую базу не смотрел, но пишет
"Stubby also has support for authentication using either user name/password or single sign-on (SSO) tokens. A solution for accessing SSL-protected URLs is also available."
валяется на openntf.org

ещё на мысль - оставил на sysadmins
 
T

turumbay

Использую HttpsURLConnection.getOutputStream(). Попробовал явно выставить
HttpsURLConnection.setFollowRedirects(true);
urlConn.setInstanceFollowRedirects(true); — безрезультатно. Попробую погрызть печеньки :). Смущает только заявление в справке по веб-сервисам, что поддерживаются только пост-запросы.
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">ну вот как-то так работает</div></div><div class="sp-body"><div class="sp-content">
Код:
package ru.turumbay.forum34
// пример коннекта к домине с авторизацией по http 
import java.io.*;
import java.net.*;

class DominoHTTPConnection{
private String serverAddress = "";
private String sessionId = "";
DominoHTTPConnection( String serverAddress , String sessionId ){
this.serverAddress = serverAddress;
this.sessionId = sessionId;
}

DominoHTTPConnection( String serverAddress , String login , String password ){
this.serverAddress = serverAddress;
login( login , password );
}

private void login(String login,String password) {
HttpURLConnection connection = null;
try {
String loginData = "Username=" + login + "&Password=" + password;
URL url = new URL( serverAddress + "/names.nsf?login");
connection = doPost(url, loginData, "");
sessionId = getSessionId(connection);
if ( sessionId.equals("") ) /* (sessionId == "" ) */ // см. замечание nvy двумя постами ниже
throw new IllegalArgumentException("Can't create session"); 
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
closeConnection( connection );
}
}
private void closeConnection( HttpURLConnection connection ){
if (connection != null) {
connection.disconnect();
}
}

private HttpURLConnection doPost(URL url, String postData, String sessionId) throws IOException {
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Content-Length", Integer.toString(postData.getBytes().length));
connection.setRequestProperty("Content-Language", "en-US");
connection.setRequestProperty("Cookie", sessionId);

connection.setInstanceFollowRedirects(false);
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);

DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
wr.writeBytes(postData);
wr.flush();
wr.close();
return connection;
}

private String getSessionId(HttpURLConnection connection) {
String cookieVal = connection.getHeaderField("Set-Cookie");
if (cookieVal == null) 
return "";
return cookieVal.substring(0, cookieVal.indexOf(";"));
}

public String doPost( String path , String postData ){
HttpURLConnection connection = null;
try {
URL url = new URL( serverAddress + path );
connection = doPost( url , postData , sessionId);
return getResponseText( connection );
} catch ( Exception e ){
throw new RuntimeException( e );
} finally {
closeConnection( connection );
}
}

private String getResponseText( HttpURLConnection connection ) throws IOException{
BufferedReader rd = null;
try {
rd = new BufferedReader(
new InputStreamReader(connection.getInputStream()));
String line;
StringBuffer response = new StringBuffer();
while ((line = rd.readLine()) != null) {
response.append(line);
response.append('\r');
}
return response.toString();
} finally {
rd.close();
}
}

public String getSessionId(){
return sessionId;
}

}


public class NvyExample {
public static void main( String [] args ){
DominoHTTPConnection domino = new DominoHTTPConnection( "http://domino.acme.com" , "login" , "password" );
String res = domino.doPost( "/replicaId/_/unid" , "" );
System.out.println( res );
// новый запрос с использованием старой куки
DominoHTTPConnection anotherDominoConnection = new DominoHTTPConnection( "http://domino.acme.com" , domino.getSessionId() );

}
}
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 985
611
BIT
473
ну тогдауж и такой ФУЙ
 
N

nvyush

turumbay
В ставил предложенный код, слегка доработав напильником (Netbeans в частности предложил вместо if(sessionId == "") написать if(sessionId.equals("")) ) получил новую проблему. Запрос возвращает:
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">xml с сообщением об ошибке</div></div><div class="sp-body"><div class="sp-content">
Код:
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<soapenv:Fault>
<faultcode>soapenv:Server.generalException</faultcode>
<faultstring>java.lang.NullPointerException</faultstring>
<detail/>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>
<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">Код веб-сервиса:</div></div><div class="sp-body"><div class="sp-content">
Код:
public class jStoreRequest {
public java.lang.String getTestString(java.lang.String testString) {
return testString;
}
}
Не пойму, в чём теперь проблема
 

lmike

нет, пердело совершенство
Lotus Team
27.08.2008
7 985
611
BIT
473
а где вызов-то, что серверу отдаётся?
надо поднять потобный сервис на родном (для нетбинс) аппсервере, проверить, а потом нести в домину
 
N

nvyush

Заработало. Просто запрос копипакостил из другого места и кое-где не всё исправил. Всем сочувствовавшим огромное спасибо.
 
T

turumbay

Не пойму, в чём теперь проблема
нетбинс перестраховываеца. В данном случае - напрасно(одна и та же строка из пула), но вообще конечно дурной тон сравнивать строки по ссылке, так что замечание принято. пример слепил на скорую руку, поэтому косяки не исключаюца...
а насчет ответа сервиса - lmike прав. где код-то? что отдается серверу и где wsdl-ка?
 

rinsk

Lotus Team
12.11.2009
1 156
126
BIT
47
Здравствуйте все!
Может вопрос глупый, но ответа на форуме не нашёл. Нужно из стороннего клиента (не Лотус) вызвать веб-сервис на сервере Домино. Если подключаться из браузера, выводится форма запроса логина/пароля. Когда делаю пост-запрос из клиента в ответ получаю текст html этой самой формы авторизации. Как передать логин/пароль и вызвать submit этой формы? Под веб ничего ранее писать не приходилось.

Коллеги по моему чот много-много написали... Чтоб не парится с формами авторизации вебсервисов у домино есть такая штука - Override Session Authentication... как раз для него и под RSS заточено..
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!