Mercurial > pub > Impl
changeset 52:15d720913562
security in work
author | wizard@linux-odin.local |
---|---|
date | Tue, 02 Mar 2010 20:12:02 +0300 |
parents | a1498298d3ee |
children | f4e045e47770 |
files | Lib/IMPL/Class/Property/Direct.pm Lib/IMPL/Security/Auth.pm Lib/IMPL/Security/Auth/AuthResult.pm Lib/IMPL/Security/Auth/Simple.pm Lib/IMPL/Web/Application.pm Lib/IMPL/Web/Application/Action.pm Lib/IMPL/Web/Response.pm Lib/IMPL/Web/Security.pm |
diffstat | 8 files changed, 228 insertions(+), 34 deletions(-) [+] |
line wrap: on
line diff
--- a/Lib/IMPL/Class/Property/Direct.pm Mon Mar 01 17:25:36 2010 +0300 +++ b/Lib/IMPL/Class/Property/Direct.pm Tue Mar 02 20:12:02 2010 +0300 @@ -22,8 +22,8 @@ my $accessor_set_no = 'die new IMPL::Exception(\'The property is read only\',$name,$class) unless $set;'; my $accessor_set = 'return( $this->{$field} = @_ == 1 ? $_[0] : [@_] );'; my $accessor_get = 'return( $this->{$field} );'; -my $list_accessor_set = 'return( @{ ($this->{$field} = ( (@_ == 1 and ref $_[0] eq \'ARRAY\') ? $_[0] : [@_] ) || [] ) } );'; -my $list_accessor_get = 'return( @{ $this->{$field} || [] } );'; +my $list_accessor_set = 'return( @{ ($this->{$field} = IMPL::Object::List->new( ( (@_ == 1 and ref $_[0] eq \'ARRAY\') ? $_[0] : [@_] ) || [] ) } );'; +my $list_accessor_get = 'return( @{ $this->{$field} ? $this->{$field} : $this->{$field} = IMPL::Object::List->new() } );'; my $custom_accessor_get = 'unshift @_, $this and goto &$get;'; my $custom_accessor_set = 'unshift @_, $this and goto &$set;';
--- a/Lib/IMPL/Security/Auth.pm Mon Mar 01 17:25:36 2010 +0300 +++ b/Lib/IMPL/Security/Auth.pm Tue Mar 02 20:12:02 2010 +0300 @@ -1,15 +1,24 @@ package IMPL::Security::Auth; +use Digest::MD5 qw(md5_hex); + use constant { - SUCCESS => 1, - INCOMPLETE => 2, - FAIL => 3 + AUTH_SUCCESS => 1, + AUTH_INCOMPLETE => 2, + AUT_FAIL => 3 }; use base qw(Exporter); -our @EXPORT_OK = qw(&SUCCESS &INCOMPLETE &FAI); -our %EXPORT_TAGS = (Const => [qw(&SUCCESS &INCOMPLETE &FAI)]); +our @EXPORT_OK = qw(&AUTH_SUCCESS &AUTH_INCOMPLETE &AUTH_FAIL &GenSSID); +our %EXPORT_TAGS = (Const => [qw(&AUTH_SUCCESS &AUTH_INCOMPLETE &AUTH_FAIL)]); + +{ + my $i = 0; + sub GenSSID() { + return md5_hex(time,rand,$i++); + } +} 1; @@ -33,4 +42,20 @@ в которм содержится уникальные свойства сессии, например идентификатор, сеансовые ключи и т.д. +Пакет аутентификации должен иметь следующий интерфейс + +=over + +=item C<CTOR($SecData)> + +Создает пакет для авторизации на основе данных безопасности для пользователя + +=item C<< $obj->DoAuth($Challenge) >> + +Производит аутентификацию пользователя и инициализацию сессии, возвращает результат аутентификации, в виде массива ($status,$challenge). + +=item C<< $obj->ValidateSession($Challenge) >> + +Производит аутентификацию сессии, возвращает результат аутентификации, в виде массива ($status,$challenge). + =cut \ No newline at end of file
--- a/Lib/IMPL/Security/Auth/AuthResult.pm Mon Mar 01 17:25:36 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,15 +0,0 @@ -package IMPL::Security::Auth::Result; -use strict; - -use base qw(IMPL::Object); -use IMPL::Class::Property; -use IMPL::Class::Property::Direct; - -BEGIN { - public _direct property State => prop_get; - public _direct property ClientSecData => prop_get; - public _direct property AuthMod => prop_get; -} - - -1;
--- a/Lib/IMPL/Security/Auth/Simple.pm Mon Mar 01 17:25:36 2010 +0300 +++ b/Lib/IMPL/Security/Auth/Simple.pm Tue Mar 02 20:12:02 2010 +0300 @@ -2,15 +2,38 @@ use base qw(IMPL::Security::Auth); use Digest::MD5; -import IMPL::Security::Auth qw(:Const); +import IMPL::Security::Auth qw(:Const GenSSID); + +use IMPL::Class::Property; + +BEGIN { + private property _passwordImage => prop_all; + private property _sessionCookie => prop_all; +} + +sub CTOR { + my ($this,$secData) = @_; + + $this->_passwordImage($secData); +} sub DoAuth { - my ($this,$clientData,$serverData) = @_; + my ($this,$challenge) = @_; - if (Digest::MD5::md5_hex($clientData) eq $serverData) { - return SUCCESS; + if (Digest::MD5::md5_hex($challenge) eq $this->_passwordImage) { + return (SUCCESS,$this->_sessionCookie(GenSSID)); } elsee { - return FAIL; + return (FAIL,undef); + } +} + +sub ValidateSession { + my ($this,$cookie) = @_; + + if ($cookie eq $this->_sessionCookie) { + return (SUCCESS,undef); + } else { + return (FAIL,undef); } }
--- a/Lib/IMPL/Web/Application.pm Mon Mar 01 17:25:36 2010 +0300 +++ b/Lib/IMPL/Web/Application.pm Tue Mar 02 20:12:02 2010 +0300 @@ -6,8 +6,7 @@ use IMPL::Class::Property; BEGIN { - public property RequestFactory => prop_all; - public property ContextInitializers => prop_all; + public property handlerError => prop_all; } # custom factory @@ -21,13 +20,15 @@ my ($this) = @_; while (my $request = $this->fetch_request()) { - my $context = $this->prepare_context($request); - $context->invoke($request); + my $action = $this->prepare_action($request); + $action->invoke($request); } } 1; +__END__ + =pod =head1 SYNOPSIS @@ -38,10 +39,17 @@ =head1 DESCRIPTION Зкземпляр приложения содержит в себе глобальные настройки, реализует контроллер запросов, +в качестве источника запросов используется CGI или иной совместимый модуль. -Получая запрос из источника запросов, создает контекст выполнения запроса -затем выполняет запрос в указанном контексте. +Процесс обработки запроса состоит из следующих частей -Контекст формируется сначала из запроса, а затем посредством набора инициализаторов +1. Получение cgi запроса +2. Вызов модуля для инициализации объекта действия +3. Инициализация контекста выполнения +4. Выполнение запроса +5. Преобразование полученных данных в тело ответа + + + =cut
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Lib/IMPL/Web/Application/Action.pm Tue Mar 02 20:12:02 2010 +0300 @@ -0,0 +1,66 @@ +package IMPL::Web::Application::Action; + +use base qw(IMPL::Object); + +use IMPL::Class::Property; + +BEGIN { + public property application => prop_get | owner_set; + public property request => prop_get | owner_set; + public property response => prop_get | owner_set; + public property code => prop_get | owner_set; + public property chainHandlers => prop_get | owner_set | prop_list; +} + +1; + +__END__ + +=pod + +=head1 DESCRIPTION + +Определяет порядок выполнения запроса, форматирует результат, инициализирует контекст. + +Объект создается обработчиком запросов, таким как C<IMPL::Web::Application::UriController>. +При этом формируется цепочка обработчиков запроса, эта цапочка будет выполняться с последнего добавленного, +причем каждый добавленный обработчик в качестве одного из параметров получает не только текущий запрос, +но и предыдущий обработчик. + +Типичная цепочка может быть такой, в порядке добавления + +$objSecCallToMethod($target,$method) +$AuthenticateMethod +$TDocumentOut($file) + +что приведет к следующей последовательности + +Action->Invoke() { + TDocumentOut->Invoke($Action,$nextHandler) { + my $result = $nextHandler() { + $AuthenticateMethod($Action,$nextHandler) { + my $context = $Action->application->security->Authenticate($Action->request,$Action->response); + return $context->Impersonate($nextHandler) { + $objSecCallToMethod->Invoke($Action,undef) { + IMPL::Security->AccessCheck($target,$method); + return $target->$method(); + } + } + } + } + $this->format($result,$Action->response->streamBody); + } +} + +или как альтернатива может быть еще + +$objSecCallToMethod($target,$method) +$AuthenticateMethod +$TransfromToSimpleData +$JSONOut + +В данной цепочке также происходит вызов метода, но его результат потом преобразуется +в простые структуры и передается JSON преобразователю. Таким образом модулю логики +не требуется знать о выходном формате, всю работу проделают дополнительные фильтры. + +=cut \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Lib/IMPL/Web/Response.pm Tue Mar 02 20:12:02 2010 +0300 @@ -0,0 +1,58 @@ +package IMPL::Web::Response; + +use base qw(IMPL::Object); + +require IMPL::Exception; + +use IMPL::Class::Property; +use HTTP::Response; + +BEGIN { + public property request => prop_get; # cgi query + public property contentType => prop_all, { validator => \&_checkHeaderPrinted }; # String + public property buffered => prop_get; # Boolean + public property cookies => prop_all, { validator => \&_checkHeaderPrinted }; # Hash + public property streamBody => { get => \&getStreamBody }; # stream + + private property _streamBody => prop_all; # stream + private property _streamOut => prop_all; # stream + private property _isHeaderPrinted => prop_all; # Boolean +} + +sub _checkHeaderPrinted { + my ($this,$value) = @_; + + die new IMPL::InvalidOperationException() if $this->_isHeaderPrinted; +} + +sub getStreamBody { + my ($this) = @_; + + return $this->_streamBody if $this->buffered; + + +} + +sub _PrintHeader { + my ($this) = @_; + + unless ($this->_isHeaderPrinted) { + $this->_isHeaderPrinted(1); + + + } +} + +sub Send { + +} + +1; + +__END__ + +=pod + + + +=cut \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Lib/IMPL/Web/Security.pm Tue Mar 02 20:12:02 2010 +0300 @@ -0,0 +1,29 @@ +package IMPL::Web::Security; + +1; + +__END__ + +=pod + +=head1 DESCRIPTION + +Модуль для аутентификации и авторизации веб запроса. + +Получает запрос, вчленяет из него информацию для авторизации, производит авторизацию пользователя +и создает контекст безопасности. + +При этом использует указанные модули аутентификации. + +Информацию для аутентификации модкль получает через соответствующие адаптеры. + +=item C<IMPL::Web::Security::Server> + +аутентифицирует пользователя на основе данных, предоставленных сервером + +=item C<IMPL::Web::Security::Embed> + +Аутентифицирует пользователя используя указанные модули, при этом получает данные +из запроса. + +=cut \ No newline at end of file