# HG changeset patch # User Sergey # Date 1270637134 -14400 # Node ID 077357224bece6c5586a265f4bc45957d45e5e0e # Parent f017c0d7527c8dcbe521ca8baf738858302b60fa IMPL::Web::Security alpha version IMPL::Security improovements diff -r f017c0d7527c -r 077357224bec Lib/IMPL/Security/Auth.pm --- a/Lib/IMPL/Security/Auth.pm Wed Apr 07 01:05:02 2010 +0400 +++ b/Lib/IMPL/Security/Auth.pm Wed Apr 07 14:45:34 2010 +0400 @@ -44,6 +44,8 @@ =head1 DESCRIPTION +C<[Abstract]> + Аутентификация носит итеративный характер, для чего создается объект аутентификации который сохраняет состояние между итерациями. @@ -94,12 +96,15 @@ Флаг того, что аутентификация закончена успешно. -=item C +=item C Производит аутентификацию пользователя и инициализацию сессии, возвращает результат аутентификации, в виде массива ($status,$challenge). -=item C +После успешной аутентификации пользователь получает данные C<$challenge> +для аутентификации сессии. + +=item C Производит аутентификацию сессии, возвращает результат аутентификации, в виде массива ($status,$challenge). diff -r f017c0d7527c -r 077357224bec Lib/IMPL/Security/Auth/Simple.pm --- a/Lib/IMPL/Security/Auth/Simple.pm Wed Apr 07 01:05:02 2010 +0400 +++ b/Lib/IMPL/Security/Auth/Simple.pm Wed Apr 07 14:45:34 2010 +0400 @@ -1,12 +1,13 @@ package IMPL::Security::Auth::Simple; use strict; -use base qw(IMPL::Security::Auth); +use base qw(IMPL::Object IMPL::Security::Auth); use Digest::MD5; use IMPL::Class::Property; +use IMPL::Security::Auth qw(:Const); -BEGIN { +BEGIN { private property _passwordImage => prop_all; private property _sessionCookie => prop_all; } @@ -14,7 +15,26 @@ sub CTOR { my ($this,$secData) = @_; - $this->_passwordImage($secData); + my ($passImg,$cookie) = split /|/,$secData; + + $this->_passwordImage($passImg); + $this->_sessionCookie($cookie); +} + +sub secData { + my ($this) = @_; + + if ($this->_sessionCookie) { + return join ('|',$this->_passwordImage, $this->_sessionCookie ); + } else { + return $this->_passwordImage; + } +} + +sub isTrusted { + my ($this) = @_; + + $this->_sessionCookie ? 1 : 0; } sub DoAuth { @@ -23,13 +43,15 @@ if (Digest::MD5::md5_hex($challenge) eq $this->_passwordImage) { return (AUTH_SUCCESS,$this->_sessionCookie($this->GenSSID)); } elsee { - return (AUTH_FAIL,undef); + return (AUTH_FAIL,$this->_sessionCookie(undef)); } } sub ValidateSession { my ($this,$cookie) = @_; + die new IMPL::InvalidOperationException("The context is untrusted") unless $this->_sessionCookie; + if ($cookie eq $this->_sessionCookie) { return (AUTH_SUCCESS,undef); } else { @@ -67,6 +89,20 @@ =over +=item C + +Создает объект аутентификации, передавая ему данные для инициализации. + +=item C<[get]secData> + +Возвращает данные безопасности, которые можно использовать для восстановления +состояния объекта. + +=item C<[get]isTrusted> + +Является ли объект доверенным для аутентификации сессии (тоесть хранит данные +для аутентификации сессии). + =item C Аутентифицирует пользователя. Используется один этап. C<$challenge> diff -r f017c0d7527c -r 077357224bec Lib/IMPL/Security/Context.pm --- a/Lib/IMPL/Security/Context.pm Wed Apr 07 01:05:02 2010 +0400 +++ b/Lib/IMPL/Security/Context.pm Wed Apr 07 14:45:34 2010 +0400 @@ -42,6 +42,16 @@ } } +sub isTrusted { + my ($this) = @_; + + if (my $auth = $this->auth) { + return $auth->isTrusted; + } else { + return 0; + } +} + sub nobody { my ($self) = @_; $nobody = $self->new(principal => IMPL::Security::Principal->nobody, rolesAssigned => undef) unless $nobody; @@ -106,6 +116,10 @@ Объект асторизации C, использованный при создании текущего контекста. +=item C<[get] isTrusted> + +Возвращает значение является ли контекст доверенным, тоесть сессия аутетифицирована. + =item C Делает контекст текущим и выполняет в нем функцию по ссылке C<$code>. По окончании diff -r f017c0d7527c -r 077357224bec Lib/IMPL/Web/Security.pm --- a/Lib/IMPL/Web/Security.pm Wed Apr 07 01:05:02 2010 +0400 +++ b/Lib/IMPL/Web/Security.pm Wed Apr 07 14:45:34 2010 +0400 @@ -1,34 +1,54 @@ package IMPL::Web::Security; - +use strict; use base qw(IMPL::Object IMPL::Security IMPL::Object::Autofill); +require IMPL::Web::Security::Session; + use IMPL::Class::Property; +use IMPL::Security::Auth qw(:Const); __PACKAGE__->PassThroughArgs; BEGIN { - public property source => prop_all; -} - -sub CTOR { - my ($this) = @_; - - $this->dataSource or die new IMPL::InvalidArgumentException("The argument is required",'dataSource'); + public property sourceUser => prop_all; + public property sourceSession => prop_all; } -sub RetrSession { - my ($this,$sid) = @_; +sub AuthUser { + my ($this,$name,$package,$challenge) = @_; + + my $user = $this->sourceUser->search({name => $name}); + + my $auth; + if ( my $secData = $user->secData($package) ) { + $auth = $package->new($secData); + } else { + die new IMPL::SecurityException("Authentication failed","A sec data for the $package isn't found"); + } - return $this->source->RetrSession(id => $sid); + my ($status,$answer) = $auth->DoAuth($challenge); + + if ($status == AUTH_FAIL) { + die new IMPL::SecurityException("Authentication failed","DoAuth failed"); + } + + return { + status => $status, + answer => $answer, + context => $this->MakeContext( $user, $user->roles, $auth ) + } } -sub RetrSecData { - my ($this,$user,$secPackage) = @_; +sub MakeContext { + my ($this,$principal,$roles,$auth) = @_; - $user = ref $user ? $user->name : $user; - - return - $this->source->RetrSecData(user => $user, package => $secPackage); + return $this->sourceSession->insert( + { + principal => $principal, + rolesAssigned => $roles, + auth => $auth + } + ); } 1; diff -r f017c0d7527c -r 077357224bec impl.kpf --- a/impl.kpf Wed Apr 07 01:05:02 2010 +0400 +++ b/impl.kpf Wed Apr 07 14:45:34 2010 +0400 @@ -378,6 +378,32 @@ default + + + + + + 9011 + + + Lib/IMPL/Security/Auth/Simple.pm + + Perl + + + + application/x-www-form-urlencoded + GET + 1 + 0 + 0 + + + enabled + + + default +