changeset 81:077357224bec

IMPL::Web::Security alpha version IMPL::Security improovements
author Sergey
date Wed, 07 Apr 2010 14:45:34 +0400
parents f017c0d7527c
children 3a4205e7b663
files Lib/IMPL/Security/Auth.pm Lib/IMPL/Security/Auth/Simple.pm Lib/IMPL/Security/Context.pm Lib/IMPL/Web/Security.pm impl.kpf
diffstat 5 files changed, 124 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- 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<DoAuth($Challenge)>
+=item C<DoAuth($challenge)>
 
 Производит аутентификацию пользователя и инициализацию сессии,
 возвращает результат аутентификации, в виде массива ($status,$challenge).
 
-=item C<ValidateSession($Challenge)>
+После успешной аутентификации пользователь получает данные C<$challenge>
+для аутентификации сессии.
+
+=item C<ValidateSession($challenge)>
 
 Производит аутентификацию сессии, возвращает результат аутентификации,
 в виде массива ($status,$challenge).
--- 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<CTOR($secData)>
+
+Создает объект аутентификации, передавая ему данные для инициализации.
+
+=item C<[get]secData>
+
+Возвращает данные безопасности, которые можно использовать для восстановления
+состояния объекта.
+
+=item C<[get]isTrusted>
+
+Является ли объект доверенным для аутентификации сессии (тоесть хранит данные
+для аутентификации сессии).
+
 =item C<DoAuth($challenge)>
 
 Аутентифицирует пользователя. Используется один этап. C<$challenge>
--- 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<IMPL::Security::Auth>, использованный при создании текущего контекста.
 
+=item C<[get] isTrusted>
+
+Возвращает значение является ли контекст доверенным, тоесть сессия аутетифицирована.
+
 =item C<Impersonate($code)>
 
 Делает контекст текущим и выполняет в нем функцию по ссылке C<$code>. По окончании
--- 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;
--- 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 @@
 </preference-set>
   <string id="lastInvocation">default</string>
 </preference-set>
+<preference-set idref="66c7d414-175f-45b6-92fe-dbda51c64843/Lib/IMPL/Security/Auth/Simple.pm">
+<preference-set id="Invocations">
+<preference-set id="default">
+  <string id="cookieparams"></string>
+  <string id="cwd"></string>
+  <long id="debugger.io-port">9011</long>
+  <string id="documentRoot"></string>
+  <string id="executable-params"></string>
+  <string relative="path" id="filename">Lib/IMPL/Security/Auth/Simple.pm</string>
+  <string id="getparams"></string>
+  <string id="language">Perl</string>
+  <string id="mpostparams"></string>
+  <string id="params"></string>
+  <string id="postparams"></string>
+  <string id="posttype">application/x-www-form-urlencoded</string>
+  <string id="request-method">GET</string>
+  <boolean id="show-dialog">1</boolean>
+  <boolean id="sim-cgi">0</boolean>
+  <boolean id="use-console">0</boolean>
+  <string id="userCGIEnvironment"></string>
+  <string id="userEnvironment"></string>
+  <string id="warnings">enabled</string>
+</preference-set>
+</preference-set>
+  <string id="lastInvocation">default</string>
+</preference-set>
 <preference-set idref="66c7d414-175f-45b6-92fe-dbda51c64843/_test/DOM.t">
 <preference-set id="Invocations">
 <preference-set id="default">