From 3f5229142af88f0cc44644cc756d908138e5a790 Mon Sep 17 00:00:00 2001 From: xue <> Date: Sun, 16 Sep 2007 19:32:58 +0000 Subject: Make auth rules more consistently handled. --- .../quickstart/protected/pages/Advanced/Auth.page | 10 ++-- framework/Security/TAuthManager.php | 2 +- framework/Security/TAuthorizationRule.php | 68 +++++++++++++++------- framework/Web/Services/TPageService.php | 4 +- 4 files changed, 54 insertions(+), 30 deletions(-) diff --git a/demos/quickstart/protected/pages/Advanced/Auth.page b/demos/quickstart/protected/pages/Advanced/Auth.page index 1c89e07d..531b8bdf 100644 --- a/demos/quickstart/protected/pages/Advanced/Auth.page +++ b/demos/quickstart/protected/pages/Advanced/Auth.page @@ -56,10 +56,10 @@ Authorization rules for pages are specified in -
  • pages - list of comma-separated page names that this rule applies to. If empty or not set, this rule will apply to all pages under the current directory and all its subdirectories recursively.
  • -
  • users - list of comma-separated user names that this rule applies to. A character * refers to all users including anonymous/guest user. A character ? refers to anonymous/guest user. And a character @ refers to authenticated users (available since v3.1).
  • -
  • roles - list of comma-separated user roles that this rule applies to.
  • -
  • verb - page access method that this rule applies to. It can be either get or post. If empty or not set, the rule applies to both methods.
  • +
  • pages - list of comma-separated page names that this rule applies to. If empty, not set or wildcard '*', this rule will apply to all pages under the current directory and all its subdirectories recursively.
  • +
  • users - list of comma-separated user names that this rule applies to. If empty, not set or wildcard '*', this rule will apply to all users including anonymous/guest user. A character ? refers to anonymous/guest user. And a character @ refers to authenticated users (available since v3.1).
  • +
  • roles - list of comma-separated user roles that this rule applies to. If empty, not set or wildcard '*', this rule will apply to all user roles.
  • +
  • verb - page access method that this rule applies to. It can be either get or post. If empty, not set or wildcard '*', the rule will apply to both methods.
  • @@ -80,7 +80,7 @@ Since version 3.1.1, the pages attribute in the authorization rules can

    -Also introduced in version 3.1.1 are IP rules. They are specified by a new attribute ip in authorization rules. The IP rules are used to determine if an authorization rule aplies to an end-user according to his IP address. One can list a few IPs together, separated by comma ','. Wildcard '*' can be used in the rules. For example, ip="192.168.0.2, 192.168.1.*" means the rule applies to users whose IP address is 192.168.0.2 or 192.168.1.*. The latter matches any host in the subnet 192.168.1. +Also introduced in version 3.1.1 are IP rules. They are specified by a new attribute ips in authorization rules. The IP rules are used to determine if an authorization rule aplies to an end-user according to his IP address. One can list a few IPs together, separated by comma ','. Wildcard '*' can be used in the rules. For example, ips="192.168.0.2, 192.168.1.*" means the rule applies to users whose IP address is 192.168.0.2 or 192.168.1.*. The latter matches any host in the subnet 192.168.1. If the attribute 'ips' is empty, not set or wildcard '*', the corresponding rule will apply to requests coming from any host address.

    Using TUserManager

    diff --git a/framework/Security/TAuthManager.php b/framework/Security/TAuthManager.php index cbad51dc..fcbb64d2 100644 --- a/framework/Security/TAuthManager.php +++ b/framework/Security/TAuthManager.php @@ -251,7 +251,7 @@ class TAuthManager extends TModule $application=$this->getApplication(); if($this->hasEventHandler('OnAuthorize')) $this->raiseEvent('OnAuthorize',$this,$application); - if(!$application->getAuthorizationRules()->isUserAllowed($application->getUser(),$application->getRequest()->getRequestType())) + if(!$application->getAuthorizationRules()->isUserAllowed($application->getUser(),$application->getRequest()->getRequestType(),$application->getRequest()->getUserHostAddress())) { $application->getResponse()->setStatusCode(401); $application->completeRequest(); diff --git a/framework/Security/TAuthorizationRule.php b/framework/Security/TAuthorizationRule.php index 42a11412..bdc0e902 100644 --- a/framework/Security/TAuthorizationRule.php +++ b/framework/Security/TAuthorizationRule.php @@ -85,6 +85,9 @@ class TAuthorizationRule extends TComponent $this->_everyone=false; $this->_guest=false; $this->_authenticated=false; + + if(trim($users)==='') + $users='*'; foreach(explode(',',$users) as $user) { if(($user=trim(strtolower($user)))!=='') @@ -102,16 +105,24 @@ class TAuthorizationRule extends TComponent $this->_users[]=$user; } } + + if(trim($roles)==='') + $roles='*'; foreach(explode(',',$roles) as $role) { if(($role=trim(strtolower($role)))!=='') $this->_roles[]=$role; } - $verb=trim(strtolower($verb)); - if($verb==='' || $verb==='get' || $verb==='post') + + if(($verb=trim(strtolower($verb)))==='') + $verb='*'; + if($verb==='*' || $verb==='get' || $verb==='post') $this->_verb=$verb; else throw new TInvalidDataValueException('authorizationrule_verb_invalid',$verb); + + if(trim($ipRules)==='') + $ipRules='*'; foreach(explode(',',$ipRules) as $ipRule) { if(($ipRule=trim($ipRule))!=='') @@ -185,38 +196,50 @@ class TAuthorizationRule extends TComponent } /** + * @param IUser the user object + * @param string the request verb (GET, PUT) + * @param string the request IP address * @return integer 1 if the user is allowed, -1 if the user is denied, 0 if the rule does not apply to the user */ - public function isUserAllowed(IUser $user,$verb) + public function isUserAllowed(IUser $user,$verb,$ip) { - $decision=($this->_action==='allow')?1:-1; - if($this->_verb==='' || strcasecmp($verb,$this->_verb)===0) - { - if(!$this->isHostAddressMatched()) - return 0; - if($this->_everyone || ($this->_guest && $user->getIsGuest()) || ($this->_authenticated && !$user->getIsGuest())) - return $decision; - if(in_array(strtolower($user->getName()),$this->_users)) - return $decision; - foreach($this->_roles as $role) - if($user->isInRole($role)) - return $decision; - } - return 0; + if($this->isVerbMatched($verb) && $this->isIpMatched($ip) && $this->isUserMatched($user) && $this->isRoleMatched($user)) + return ($this->_action==='allow')?1:-1; + else + return 0; } - private function isHostAddressMatched() + private function isIpMatched($ip) { if(empty($this->_ipRules)) return 1; - $ip=Prado::getApplication()->getRequest()->getUserHostAddress(); foreach($this->_ipRules as $rule) { - if($rule===$ip || (($pos=strpos($rule,'*'))!==false && strncmp($ip,$rule,$pos)===0)) + if($rule==='*' || $rule===$ip || (($pos=strpos($rule,'*'))!==false && strncmp($ip,$rule,$pos)===0)) return 1; } return 0; } + + private function isUserMatched($user) + { + return ($this->_everyone || ($this->_guest && $user->getIsGuest()) || ($this->_authenticated && !$user->getIsGuest())); + } + + private function isRoleMatched($user) + { + foreach($this->_roles as $role) + { + if($role==='*' || $user->isInRole($role)) + return true; + } + return false; + } + + private function isVerbMatched($verb) + { + return ($this->_verb==='*' || strcasecmp($verb,$this->_verb)===0); + } } @@ -235,16 +258,17 @@ class TAuthorizationRuleCollection extends TList /** * @param IUser the user to be authorized * @param string verb, can be empty, 'post' or 'get'. + * @param string the request IP address * @return boolean whether the user is allowed */ - public function isUserAllowed($user,$verb) + public function isUserAllowed($user,$verb,$ip) { if($user instanceof IUser) { $verb=strtolower(trim($verb)); foreach($this as $rule) { - if(($decision=$rule->isUserAllowed($user,$verb))!==0) + if(($decision=$rule->isUserAllowed($user,$verb,$ip))!==0) return ($decision>0); } return true; diff --git a/framework/Web/Services/TPageService.php b/framework/Web/Services/TPageService.php index ced01641..568e9a40 100644 --- a/framework/Web/Services/TPageService.php +++ b/framework/Web/Services/TPageService.php @@ -653,7 +653,7 @@ class TPageConfiguration extends TComponent { $patterns=$node->getAttribute('pages'); $ruleApplies=false; - if(empty($patterns)) // null or empty string + if(empty($patterns) || trim($patterns)==='*') // null or empty string $ruleApplies=true; else { @@ -681,7 +681,7 @@ class TPageConfiguration extends TComponent } } if($ruleApplies) - $rules[]=new TAuthorizationRule($node->getTagName(),$node->getAttribute('users'),$node->getAttribute('roles'),$node->getAttribute('verb'),$node->getAttribute('ip')); + $rules[]=new TAuthorizationRule($node->getTagName(),$node->getAttribute('users'),$node->getAttribute('roles'),$node->getAttribute('verb'),$node->getAttribute('ips')); } $this->_rules=array_merge($rules,$this->_rules); } -- cgit v1.2.3