Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Распределенный сервер баз данных. Как залогинить пользователя?

1
08 августа 2005 года
kot_
7.3K / / 20.01.2000
Предлагаю в эту ветку постить все, что связанно с распеределенными объектами в С++. Т.е. СОМ, DCOM и СОМ+. Я когда приведу в божеский вид проект постараюсь сгруппировать по шагам создание сервера и размещу так сказать с конечным результатом.

###############################################
###############################################
###############################################

Ситуация в следующем - в приложении используется удаленный модуль данных(RDM), который содержит компоненты: TDataSetProvaider,TADOStoredProcedure,TADOConnection.
Вопрос в следующем - существует ли стандартный механизм ввода имени пользователя и пароля для TADOConnection (если LoginPromt установлено в true)на стороне клиента или как это можно реализовать не сохраняя пароль?
Сейчас если LoginPromt тру - при попытке клиента приконектится вылетает ошибка соединения (пароль пользователя не верен). А мне необходимо реализовать работу юзеров каждого под своим логином. На клиенте используется TSocketConnection.
2.1K
08 августа 2005 года
greyich
117 / / 02.02.2005
Цитата:
Originally posted by kot_
Ситуация в следующем - в приложении используется удаленный модуль данных(RDM), который содержит компоненты: TDataSetProvaider,TADOStoredProcedure,TADOConnection.
Вопрос в следующем - существует ли стандартный механизм ввода имени пользователя и пароля для TADOConnection (если LoginPromt установлено в true)на стороне клиента или как это можно реализовать не сохраняя пароль?
Сейчас если LoginPromt тру - при попытке клиента приконектится вылетает ошибка соединения (пароль пользователя не верен). А мне необходимо реализовать работу юзеров каждого под своим логином. На клиенте используется TSocketConnection.


а на сервере точно стоит аутентификация собственными средставми? а не через active directory

1
08 августа 2005 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by greyich
а на сервере точно стоит аутентификация собственными средставми? а не через active directory


Да, параметры аутендификации на SQL-servere установлены собственными средствами. Если коннектится к нему на прямую - проблем не возникает. Но по удаленному доступу это не работает.

1
08 августа 2005 года
kot_
7.3K / / 20.01.2000
Вероятно, у провайдера должно быть свойство, позволяющее сформировать строку подключения. Вот только не могу понять - какое. Вроде ни в одном из методов параметры аутоиндификации не передаются.
1
30 августа 2005 года
kot_
7.3K / / 20.01.2000
Вобщем работает это так:
 
Код:
InOTCRemouteModuleDisp T(LPDISPATCH(scClient->AppServer));
   OleVariant L = (Username+"@"+Password);
   T.AS_Login(L);

Естественно необходимо определить метод интерфейса в классе удаленного модуля.
Правда с этими СОМ интерфейсам одно мучение - в связи с тем что раньше работать не приходилось, потому и возникает куча неполадок.
Первое. Странное поведение. В начале в метод передавал 2 параметра. Не работало, кричало, интерфейс неопределен. Сделал так:
 
Код:
InOTCRemouteModuleDisp T;
T.BindDefoult();
   OleVariant L = (Username+"@"+Password);
   T.AS_Login(L);

Заработало. Стало работать и в первом варианте Правда юзерский дата сет начал ругатся. Выскакиват экзыпшен "Аргументы имеют неверный тип,выходят за пределы диапазона или конфликтуют друг с другом". Хм.
Соответственно возникает вопрос - че ему надо?В билдеровской справке, такой же метод определен вроде как ОлеВариант, но один. Переделал. Перестало работать все.:) Перезагрузился. Заработало.:)Правда исключение вылетает по прежнему. Буду разбираться... Правда в чем бока понять пока не могу. Читаю СОМ. :)^):)
246
31 августа 2005 года
GIZMO
1.8K / / 30.07.2004
Цитата:
Originally posted by kot_
Вобщем работает это так:
 
Код:
InOTCRemouteModuleDisp T(LPDISPATCH(scClient->AppServer));
   OleVariant L = (Username+"@"+Password);
   T.AS_Login(L);

Естественно необходимо определить метод интерфейса в классе удаленного модуля.
Правда с этими СОМ интерфейсам одно мучение - в связи с тем что раньше работать не приходилось, потому и возникает куча неполадок.
Первое. Странное поведение. В начале в метод передавал 2 параметра. Не работало, кричало, интерфейс неопределен. Сделал так:
 
Код:
InOTCRemouteModuleDisp T;
T.BindDefoult();
   OleVariant L = (Username+"@"+Password);
   T.AS_Login(L);

Заработало. Стало работать и в первом варианте Правда юзерский дата сет начал ругатся. Выскакиват экзыпшен "Аргументы имеют неверный тип,выходят за пределы диапазона или конфликтуют друг с другом". Хм.
Соответственно возникает вопрос - че ему надо?В билдеровской справке, такой же метод определен вроде как ОлеВариант, но один. Переделал. Перестало работать все.:) Перезагрузился. Заработало.:)Правда исключение вылетает по прежнему. Буду разбираться... Правда в чем бока понять пока не могу. Читаю СОМ. :)^):)


На сервере в TypeLibrary создаешь новый метод, у него два параметра типа BSTR, Refresh

 
Код:
STDMETHODIMP TMyIntefaceImpl::Login(BSTR user, BSTR password)
{
    try
    {
        ...
       
//проверить есть ли такой юзнер, установить пареметры набору данных и активировать его

на стороне клиента
 
Код:
Variant svr = scClient->AppServer;
svr.OleProcedure("Login", Eduser->Text, Edpassword.text);
//открыть scClient
...

примерно так, код найти не могу похерил, но все работало.
1
31 августа 2005 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by GIZMO
На сервере в TypeLibrary создаешь новый метод, у него два параметра типа BSTR, Refresh
 
Код:
STDMETHODIMP TMyIntefaceImpl::Login(BSTR user, BSTR password)
{
    try
    {
        ...
       
//проверить есть ли такой юзнер, установить пареметры набору данных и активировать его

на стороне клиента
 
Код:
Variant svr = scClient->AppServer;
svr.OleProcedure("Login", Eduser->Text, Edpassword.text);
//открыть scClient
...

примерно так, код найти не могу похерил, но все работало.


Спасибо. Работает.
да и так тоже работает:

 
Код:
if(!m_remoute.IsBound())
OleCheck(ConOTCRemouteModule::Create(m_remoute));
OleCheck(m_remoute.AS_Login(L));

но мой вариант имеет один не достаток - он инициализирует удаленній сервер дважды. Благодаря твоему коду выяснил как это убрать.
Но проблема и в одном случае и в другом одна и та же. Я почему то не могу обратится к компонентам расположенным в ремотемодуле. Т.е. код на сервере (окна собщений и получение строки имени и пароля - исключительно для проверки):
Код:
WideString S = (Login.bstrVal);
   WideString P = S.SubString(S.Pos("@")+1,S.Length());
   WideString U = S.SubString(1,S.Pos("@")-1);
   ShowMessage(WideCharToString(P)+" "+WideCharToString(U));
    //WideString P = Pass.bstrVal;WideString U = Login.bstrVal;
   WideString str = "Provider=SQLOLEDB.1;Password="+P+";Persist Security Info=True;User ID="+U+";Initial Catalog=ncredcom;Data Source=(local)";
   ShowMessage (WideCharToString(str));//Вот этот мессага появляется
 //А вот эта уж нет.  ShowMessage(WideCharToString(nOTCRemouteModule->adoConnect->ConnectionString));
   nOTCRemouteModule->adoConnect->ConnectionString = str;
    ShowMessage("Strocf");
  try{
   ShowMessage("Begin");
   nOTCRemouteModule->adoConnect->Connected = true;
    ShowMessage("End");
   nOTCRemouteModule->adoSelect->Active = true;
    ShowMessage("Begin");
     }
   catch(Exception &e){
    return Error(e.Message.c_str(),IID_InOTCRemouteModule);
   }
   return S_OK;

Ошибка оченно информативная - "Ошибка на сервере" :)
Сейчас разбираюсь, возможно проблема связана с неверной инициализацией, или какими-то особенностями удаленного модуля данных. Потому как в стандартном модуле данная конструкция работает без проблем.
Или может быть это связано с потоковой моделью? Для данного сервера модель используется Фри. И необходимо проверять заблокирован объект или нет? тогда чем заблокирован?
246
31 августа 2005 года
GIZMO
1.8K / / 30.07.2004
Цитата:
Originally posted by kot_
Сейчас разбираюсь, возможно проблема связана с неверной инициализацией, или какими-то особенностями удаленного модуля данных. Потому как в стандартном модуле данная конструкция работает без проблем.
Или может быть это связано с потоковой моделью? Для данного сервера модель используется Фри. И необходимо проверять заблокирован объект или нет? тогда чем заблокирован?


Если бы это был набор BDE то рекомендовал -TSession. Попробуй в вставить:

 
Код:
static TCOMCriticalSection cs;

STDMETHODIMP TMyIntefaceImpl::Login(BSTR user, BSTR password)
{
    TCOMCriticalSection::Lock Lock(cs);
    //обращение к наборам данных
1
31 августа 2005 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by GIZMO
Если бы это был набор BDE то рекомендовал -TSession. Попробуй в вставить:
 
Код:
static TCOMCriticalSection cs;

STDMETHODIMP TMyIntefaceImpl::Login(BSTR user, BSTR password)
{
    TCOMCriticalSection::Lock Lock(cs);
    //обращение к наборам данных


Нет, пробовал, проблема остается.

1
31 августа 2005 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by kot_
Нет, пробовал, проблема остается.


Не знаю - окончательное ли это решение проблемы - но правильный вариант такой:

Код:
//Определение метода
STDMETHODIMP TnOTCRemouteModuleImpl::AS_Login(VARIANT Login)
{
   WideString S = (Login.bstrVal);
   WideString P = S.SubString(S.Pos("@")+1,S.Length());
   WideString U = S.SubString(1,S.Pos("@")-1);
   WideString str = "Provider=SQLOLEDB.1;Password="+P+";Persist Security Info=True;User ID="+U+";Initial Catalog=ncredcom;Data Source=(local)";
   Form1->SetConnect(str);
   return S_OK;

}

 
Код:
//Реализация функции
void __fastcall TForm1::SetConnect(const WideString &str){
 adoConnect->ConnectionString = str;
 adoConnect->Connected = true;
 adoSelect->Active = true;
 return;
}

То есть, вынесение данных на форму, проблему решило. Остается открытым вопрос с блокировками - честно говоря еще не знаю как поведет себя сервер с несколькими пользователями и надо ли генерировать исключение на стороне сервера в случае например неверного логина - или сервер сгенерет его сам вобщем вопросы навеное еще будут :)
1
31 августа 2005 года
kot_
7.3K / / 20.01.2000
Небольшая поправка к написанному. Для нормальной работы с пользователями необходимо использовать датамодуль в виде:
Код:
static TCriticalSection *cs;
__fastcall TnOTCRemouteModule::TnOTCRemouteModule(TComponent* Owner) : TCRemoteDataModule(Owner)
{
  cs = new TCriticalSection;
 cs->Acquire();
  dmMain = new TdmMain(this);
}
STDMETHODIMP TnOTCRemouteModuleImpl::AS_Login(VARIANT Login)
{
   WideString S = (Login.bstrVal);
   WideString P = S.SubString(S.Pos("@")+1,S.Length());
   WideString U = S.SubString(1,S.Pos("@")-1);
   WideString str = "Provider=SQLOLEDB.1;Password="+P+";Persist Security Info=True;User ID="+U+";Initial Catalog=ncredcom;Data Source=(local)";
   dmMain->SetConnect(str);
   return S_OK;

}
void __fastcall TnOTCRemouteModule::CRemoteDataModuleDestroy(
      TObject *Sender)
{
 
cs->Release();
delete cs;
delete dmMain;

}

Вот такие пирожки с котятами.
Одна из проблем с которыми столкнулся - при закрытии приложения - вылетает ошибка доступа на сервере. Если не вызывать делиты - то проблем вроде нет но отжирается память. :(
Будет еще чего интересного - выложу.
1
04 ноября 2005 года
kot_
7.3K / / 20.01.2000
Подскажите плиз, где можно посмотреть инфу по потоковой модели Both - в чем ее особенность? Я так понимаю, что в это модели можно использовать COM+ - но где об этом можно прочесть? В руководстве разработчика сказано - этот потоковый тип здесь не рассматривается.
1
05 ноября 2005 года
kot_
7.3K / / 20.01.2000
Вобщем уперся на сейчас в одну (возможно!) проблему.
В проекте программа должна работать следующим образом:
1. Вызывается удаленный СОМ-сервер.
2. При успешном вызове - вызывается метод авторизации в который передаются необходимые данные.
3. Процесс авторизации на сервере генерирует события - OnLogin or OnFailure.
4. Событие обрабатывается клиентом - соответственно если все путем - вызывается метод - коннект ДБ в котором создается динамически подключение к базе (создается датамодуль и т.п.), если событие не обработанно, обработанно неправильно или логин неверен - первыйнах.
5. Далее - закачка и передача данных и т.п.
Авторизация происходит не в домене - т.е. механизм виндоус использовать у меня не выходит. Это предистория.
Все работает нормально. События вызываются, клиенты логинятся и в целом все нормально кроме одного. Я не могу связать объект СОМ и внутренний объект SocketConnection. Не получается. Точнее коечто выходит. Т.е используя свойство AppServer - я могу получить доступ к методам сервера. Но я не могу подписать его на нужные мне события! То есть - если я объявляю:
 
Код:
TCOMmyCom com;
::CreateRemoute("server",com);
TCOMmeComEv events;
events.OnLogin = TgfmMain::OnLogin;
events.Connect(com);
com->LoginEmployee(login,pass,id);

замечательно но не все.
Соответственно если коннетится SocketConnection - он создает новый поток на сервере - и все мои логины ему до задницы :) Правда доступа к базе он тоже не получает. Хоть что то хорошое.
Если я пытаюсь выполнить обратную последовательность - т.е. законнектить компонент, а затем уже вызвать процедуру сервера - получаю ошибку при регистрации событий. Запарился.
Из этого я вижу несколько способов решения:
1. Дописать в копонент свойство, позволяющее подключить его к уже существующему серверу. Вроде самое простое решение и наверное попробую реализовать сегодня ночью.
2. Разобраться как это выполнить не расширяя компонент :) Сюдя по всему - мало реальная и не сбыточная мечта. Так как поля класса закрыты - доступ к ним я могу получить только через хак или в самом классе - первое не годится в связи с ненадежностью, второе - сказанно выше.
3. Использовать механизм транзакций СОМ+. Т.е. создать компонент зависящий от первого - установить его свойство транзакции в "требуется" и стартовать ее из родительского - коннекшион соответственно делать к дочернему.
Вот третий способ мне кажется наиболее оптимальным, но так как мне еще не приходилось реализовать приложения COM+, ну кроме тестового сегодня ночью :), подскажите плиз, правильны ли мои выкладки - и желательно - что необходимо может учесть при этом. Естетвенно, если кто либо чтото подобное делал.
Тестовый сервер у меня стартовал нормально - правда я не успел протестировать работу методов и событий и еще не до конца разобрался с транзакциями в СОМ+. Займусь этим сегодня - если у кого есть любимые грабли - поделитесь :)
10
05 ноября 2005 года
Freeman
3.2K / / 06.03.2004
Цитата:
Originally posted by kot_
Займусь этим сегодня - если у кого есть любимые грабли - поделитесь :)


Ой, давно это было, когда баловался удаленными модулями данных...

Я бы на твоем месте попробовал получить дополнительный, собственный интерфейс от стандартного интерфейса AppServer (или как там он называется)? Кажется, нечто подобное у меня когда-то получилось. Только вот не помню, делалось это ДО подключения пользователя или ПОСЛЕ.

1
06 ноября 2005 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by Freeman
Ой, давно это было, когда баловался удаленными модулями данных...

Я бы на твоем месте попробовал получить дополнительный, собственный интерфейс от стандартного интерфейса AppServer (или как там он называется)? Кажется, нечто подобное у меня когда-то получилось. Только вот не помню, делалось это ДО подключения пользователя или ПОСЛЕ.


Если не затруднит - небольшой пример? Потому как совсем запутался. Вызвать процедуру или функцию через Variant получается - но связать интерфейсы - невыходит хоть ты тресни. Выбивает - как правило с ошибкой доступа.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог