[smarcet] - #5006 - Refactor SubDomain matching policy

This commit is contained in:
smarcet 2013-11-26 17:53:54 -03:00
parent 494dd3d135
commit 4d5059c257
2 changed files with 101 additions and 93 deletions

View File

@ -161,24 +161,38 @@ class OpenIdAuthenticationRequestHandler extends OpenIdMessageHandler
} }
} }
$this->current_request_context->cleanTrustedData();
foreach ($this->extensions as $ext) {
$data = $ext->getTrustedData($this->current_request);
$this->current_request_context->setTrustedData($data);
}
$requested_data = $this->current_request_context->getTrustedData();
$sites = $this->trusted_sites_service->getTrustedSites($currentUser, $this->current_request->getRealm(), $requested_data);
$authorization_response = $this->authService->getUserAuthorizationResponse(); $authorization_response = $this->authService->getUserAuthorizationResponse();
if ($authorization_response == IAuthService::AuthorizationResponse_None) { if ($authorization_response == IAuthService::AuthorizationResponse_None) {
$this->current_request_context->cleanTrustedData();
foreach ($this->extensions as $ext) {
$data = $ext->getTrustedData($this->current_request);
$this->current_request_context->setTrustedData($data);
}
$requested_data = $this->current_request_context->getTrustedData();
$sites = $this->trusted_sites_service->getTrustedSites($currentUser, $this->current_request->getRealm(), $requested_data);
if (!is_null($sites) && count($sites) > 0) { if (!is_null($sites) && count($sites) > 0) {
return $this->checkTrustedSite($sites); $site = $sites[0];
$policy = $site->getAuthorizationPolicy();
switch ($policy) {
case IAuthService::AuthorizationResponse_AllowForever:
{
return $this->doAssertion();
}
break;
case IAuthService::AuthorizationResponse_DenyForever:
// black listed site
return new OpenIdIndirectGenericErrorResponse(sprintf(OpenIdErrorMessages::RealmNotAllowedByUserMessage, $site->getRealm()), null, null, $this->current_request);
break;
default:
throw new \Exception("Invalid Realm Policy");
break;
}
} else { } else {
return $this->doConsentProcess(); return $this->doConsentProcess();
} }
} else { } else {
return $this->checkAuthorizationResponse($authorization_response); return $this->checkAuthorizationResponse($authorization_response);
} }
@ -198,55 +212,6 @@ class OpenIdAuthenticationRequestHandler extends OpenIdMessageHandler
return $this->auth_strategy->doLogin($this->current_request, $this->current_request_context); return $this->auth_strategy->doLogin($this->current_request, $this->current_request_context);
} }
/**
* @param object $sites
* @return mixed|OpenIdIndirectGenericErrorResponse|OpenIdPositiveAssertionResponse
* @throws \Exception
*/
private function checkTrustedSite($sites)
{
$policy = IAuthService::AuthorizationResponse_DenyForever;
$diff = array();
//iterate over all configurations for that realm
foreach ($sites as $site) {
$policy = $site->getAuthorizationPolicy();
//if denied then break
if ($policy == IAuthService::AuthorizationResponse_DenyForever)
break;
$this->current_request_context->cleanTrustedData();
foreach ($this->extensions as $ext) {
$data = $ext->getTrustedData($this->current_request);
$this->current_request_context->setTrustedData($data);
}
$requested_data = $this->current_request_context->getTrustedData();
$trusted_data = $site->getData();
$diff = array_diff($requested_data, $trusted_data);
if (count($diff) == 0)
break;
}
switch ($policy) {
case IAuthService::AuthorizationResponse_AllowForever:
{
if (!count($diff)) //already approved request
return $this->doAssertion();
else {
return $this->doConsentProcess();
}
}
break;
case IAuthService::AuthorizationResponse_DenyForever:
// black listed site
return new OpenIdIndirectGenericErrorResponse(sprintf(OpenIdErrorMessages::RealmNotAllowedByUserMessage, $site->getRealm()), null, null, $this->current_request);
break;
default:
throw new \Exception("Invalid Realm Policy");
break;
}
}
/** /**
* Create Positive Identity Assertion * Create Positive Identity Assertion
@ -396,21 +361,8 @@ class OpenIdAuthenticationRequestHandler extends OpenIdMessageHandler
//need setup to continue //need setup to continue
return new OpenIdImmediateNegativeAssertion($this->current_request->getReturnTo()); return new OpenIdImmediateNegativeAssertion($this->current_request->getReturnTo());
} }
$site = $sites[0];
$policy = IAuthService::AuthorizationResponse_DenyForever; $policy = $site->getAuthorizationPolicy();
$diff = array();
//iterate over all configurations for that realm
foreach ($sites as $site) {
$policy = $site->getAuthorizationPolicy();
//if denied then break
if ($policy == IAuthService::AuthorizationResponse_DenyForever)
break;
$trusted_data = $site->getData();
$diff = array_diff($requested_data, $trusted_data);
if (count($diff) == 0)
break;
}
switch ($policy) { switch ($policy) {
case IAuthService::AuthorizationResponse_DenyForever: case IAuthService::AuthorizationResponse_DenyForever:
@ -421,15 +373,9 @@ class OpenIdAuthenticationRequestHandler extends OpenIdMessageHandler
break; break;
case IAuthService::AuthorizationResponse_AllowForever: case IAuthService::AuthorizationResponse_AllowForever:
{ {
return $this->doAssertion();
if (!count($diff)) //already approved request
return $this->doAssertion();
else {
//need setup to continue
return new OpenIdImmediateNegativeAssertion($this->current_request->getReturnTo());
}
} }
break; break;
default: default:
return new OpenIdIndirectGenericErrorResponse(sprintf(OpenIdErrorMessages::RealmNotAllowedByUserMessage, $this->current_request->getRealm()), null, null, $this->current_request); return new OpenIdIndirectGenericErrorResponse(sprintf(OpenIdErrorMessages::RealmNotAllowedByUserMessage, $this->current_request->getRealm()), null, null, $this->current_request);
break; break;

View File

@ -4,6 +4,7 @@ namespace services;
use openid\model\IOpenIdUser; use openid\model\IOpenIdUser;
use openid\model\ITrustedSite; use openid\model\ITrustedSite;
use openid\services\IAuthService;
use openid\services\ILogService; use openid\services\ILogService;
use openid\services\ITrustedSitesService; use openid\services\ITrustedSitesService;
use OpenIdTrustedSite; use OpenIdTrustedSite;
@ -53,20 +54,81 @@ class TrustedSitesService implements ITrustedSitesService
{ {
$sites = null; $sites = null;
try { try {
if (count($data) > 0) { //get all possible sub-domains
$json_data = json_encode($data); $sub_domains = $this->getSubDomains($realm);
$sites = OpenIdTrustedSite::where("realm", "=", $realm) //get current scheme
->where("user_id", "=", $user->getId()) $schema = $this->getScheme($realm);
->where("data", "=", $json_data) //build query....
->get(); $query = OpenIdTrustedSite::where("user_id", "=", $user->getId());
if (count($sites) > 0) //add or condition for all given sub-domains
return $sites; foreach ($sub_domains as $sub_domain) {
$query = $query->orWhere(function ($query_aux) use ($sub_domain,$schema) {
$query_aux->where('realm', '=', $schema.$sub_domain);
});
} }
$sites = OpenIdTrustedSite::where("realm", "=", $realm)->where("user_id", "=", $user->getId())->get(); //add conditions for all possible pre approved data
foreach ($data as $value) {
$query = $query->where("data", "LIKE", '%"' . $value . '"%');
}
$sites = $query->get();
} catch (\Exception $ex) { } catch (\Exception $ex) {
$this->log->error($ex); $this->log->error($ex);
} }
return $sites;
$res = array();
//iterate over all retrieved sites and check the set policies by user
foreach ($sites as $site) {
$policy = $site->getAuthorizationPolicy();
//if denied then break
if ($policy == IAuthService::AuthorizationResponse_DenyForever) {
array_push($res, $site);
break;
}
$trusted_data = $site->getData();
$diff = array_diff($data, $trusted_data);
//if pre approved data is contained or equal than a former one
if (count($diff) == 0) {
array_push($res, $site);
break;
}
}
return $res;
}
private function getScheme($url){
$url = strtolower($url);
$url = parse_url($url);
$scheme = 'http://';
if(isset($url['scheme']) && !empty($url['scheme']))
{
$scheme = $url['scheme'].'://';
}
return $scheme;
}
/**
* Get all possible sub-domains for a given url
* @param $url
* @return array
*/
private function getSubDomains($url)
{
$res = array();
$url = strtolower($url);
$url = parse_url($url);
$authority = $url['host'];
$components = explode('.', $authority);
$len = count($components);
for ($i = 0; $i < $len; $i++) {
if ($components[$i] == '*') continue;
$str = '';
for ($j = $i; $j < $len; $j++)
$str .= $components[$j] . '.';
$str = trim($str, '.');
array_push($res, '*.' . $str);
}
return $res;
} }
public function getAllTrustedSitesByUser(IOpenIdUser $user) public function getAllTrustedSitesByUser(IOpenIdUser $user)