Fix on Resource server banning:
Added some logic to prevent Resource server Banning. Also refactored a little and added more config params to Server Admin console. Change-Id: I6b2961e25bbb67f682188f1a38eedf81ce1ebcf4
This commit is contained in:
parent
a33cc901b2
commit
37e236a2bb
|
@ -51,6 +51,6 @@ return array(
|
|||
'OAuth2SecurityPolicy_MaxBearerTokenDisclosureAttempts' => 5,
|
||||
'OAuth2SecurityPolicy_MaxInvalidClientExceptionAttempts' => 10,
|
||||
'OAuth2SecurityPolicy_MaxInvalidRedeemAuthCodeAttempts' => 10,
|
||||
'OAuth2SecurityPolicy_MaxInvalidInvalidClientCredentialsAttempts' => 5,
|
||||
'OAuth2SecurityPolicy_MaxInvalidClientCredentialsAttempts' => 5,
|
||||
'Banning_Enable' => true,
|
||||
);
|
|
@ -321,20 +321,32 @@ class AdminController extends BaseController {
|
|||
|
||||
$user = $this->auth_service->getCurrentUser();
|
||||
$config_values = array();
|
||||
$dictionary = array
|
||||
(
|
||||
'MaxFailed.Login.Attempts',
|
||||
'MaxFailed.LoginAttempts.2ShowCaptcha',
|
||||
'OpenId.Private.Association.Lifetime',
|
||||
'OpenId.Session.Association.Lifetime',
|
||||
'OpenId.Nonce.Lifetime',
|
||||
'OAuth2.AuthorizationCode.Lifetime',
|
||||
'OAuth2.AccessToken.Lifetime',
|
||||
'OAuth2.IdToken.Lifetime',
|
||||
'OAuth2.RefreshToken.Lifetime',
|
||||
'OAuth2.AccessToken.Revoked.Lifetime',
|
||||
'OAuth2.AccessToken.Void.Lifetime',
|
||||
'OAuth2.RefreshToken.Revoked.Lifetime',
|
||||
'OAuth2SecurityPolicy.MaxBearerTokenDisclosureAttempts',
|
||||
'OAuth2SecurityPolicy.MinutesWithoutExceptions',
|
||||
'OAuth2SecurityPolicy.MaxInvalidClientExceptionAttempts',
|
||||
'OAuth2SecurityPolicy.MaxInvalidRedeemAuthCodeAttempts',
|
||||
'OAuth2SecurityPolicy.MaxInvalidClientCredentialsAttempts',
|
||||
);
|
||||
|
||||
$config_values['MaxFailed.Login.Attempts'] = $this->configuration_service->getConfigValue('MaxFailed.Login.Attempts');
|
||||
$config_values['MaxFailed.LoginAttempts.2ShowCaptcha'] = $this->configuration_service->getConfigValue('MaxFailed.LoginAttempts.2ShowCaptcha');
|
||||
foreach($dictionary as $key)
|
||||
$config_values[$key] = $this->configuration_service->getConfigValue($key);
|
||||
|
||||
$config_values['OpenId.Private.Association.Lifetime'] = $this->configuration_service->getConfigValue('OpenId.Private.Association.Lifetime');
|
||||
$config_values['OpenId.Session.Association.Lifetime'] = $this->configuration_service->getConfigValue('OpenId.Session.Association.Lifetime');
|
||||
$config_values['OpenId.Nonce.Lifetime'] = $this->configuration_service->getConfigValue('OpenId.Nonce.Lifetime');
|
||||
|
||||
$config_values['OAuth2.AuthorizationCode.Lifetime'] = $this->configuration_service->getConfigValue('OAuth2.AuthorizationCode.Lifetime');
|
||||
$config_values['OAuth2.AccessToken.Lifetime'] = $this->configuration_service->getConfigValue('OAuth2.AccessToken.Lifetime');
|
||||
$config_values['OAuth2.IdToken.Lifetime'] = $this->configuration_service->getConfigValue('OAuth2.IdToken.Lifetime');
|
||||
$config_values['OAuth2.RefreshToken.Lifetime'] = $this->configuration_service->getConfigValue('OAuth2.RefreshToken.Lifetime');
|
||||
|
||||
return View::make("admin.server-config", array
|
||||
return View::make("admin.server-config",
|
||||
array
|
||||
(
|
||||
"username" => $user->getFullName(),
|
||||
"user_id" => $user->getId(),
|
||||
|
@ -349,40 +361,60 @@ class AdminController extends BaseController {
|
|||
|
||||
$values = Input::all();
|
||||
|
||||
$rules = array(
|
||||
'general-max-failed-login-attempts' => 'required|integer',
|
||||
'general-max-failed-login-attempts-captcha' => 'required|integer',
|
||||
'openid-private-association-lifetime' => 'required|integer',
|
||||
'openid-session-association-lifetime' => 'required|integer',
|
||||
'openid-nonce-lifetime' => 'required|integer',
|
||||
'oauth2-auth-code-lifetime' => 'required|integer',
|
||||
'oauth2-refresh-token-lifetime' => 'required|integer',
|
||||
'oauth2-access-token-lifetime' => 'required|integer',
|
||||
'oauth2-id-token-lifetime' => 'required|integer',
|
||||
$rules = array
|
||||
(
|
||||
'general-max-failed-login-attempts' => 'required|integer',
|
||||
'general-max-failed-login-attempts-captcha' => 'required|integer',
|
||||
'openid-private-association-lifetime' => 'required|integer',
|
||||
'openid-session-association-lifetime' => 'required|integer',
|
||||
'openid-nonce-lifetime' => 'required|integer',
|
||||
'oauth2-auth-code-lifetime' => 'required|integer',
|
||||
'oauth2-refresh-token-lifetime' => 'required|integer',
|
||||
'oauth2-access-token-lifetime' => 'required|integer',
|
||||
'oauth2-id-token-lifetime' => 'required|integer',
|
||||
'oauth2-id-access-token-revoked-lifetime' => 'required|integer',
|
||||
'oauth2-id-access-token-void-lifetime' => 'required|integer',
|
||||
'oauth2-id-refresh-token-revoked-lifetime' => 'required|integer',
|
||||
'oauth2-id-security-policy-minutes-without-exceptions' => 'required|integer',
|
||||
'oauth2-id-security-policy-max-bearer-token-disclosure-attempts' => 'required|integer',
|
||||
'oauth2-id-security-policy-max-invalid-client-exception-attempts' => 'required|integer',
|
||||
'oauth2-id-security-policy-max-invalid-redeem-auth-code-attempts' => 'required|integer',
|
||||
'oauth2-id-security-policy-max-invalid-client-credentials-attempts' => 'required|integer',
|
||||
);
|
||||
|
||||
$dictionary = array(
|
||||
'general-max-failed-login-attempts' => 'MaxFailed.Login.Attempts',
|
||||
'general-max-failed-login-attempts-captcha' => 'MaxFailed.LoginAttempts.2ShowCaptcha',
|
||||
'openid-private-association-lifetime' => 'OpenId.Private.Association.Lifetime',
|
||||
'openid-session-association-lifetime' => 'OpenId.Session.Association.Lifetime',
|
||||
'openid-nonce-lifetime' => 'OpenId.Nonce.Lifetime',
|
||||
'oauth2-auth-code-lifetime' => 'OAuth2.AuthorizationCode.Lifetime',
|
||||
'oauth2-access-token-lifetime' => 'OAuth2.AccessToken.Lifetime',
|
||||
'oauth2-id-token-lifetime' => 'OAuth2.IdToken.Lifetime',
|
||||
'oauth2-refresh-token-lifetime' => 'OAuth2.RefreshToken.Lifetime',
|
||||
$dictionary = array
|
||||
(
|
||||
'general-max-failed-login-attempts' => 'MaxFailed.Login.Attempts',
|
||||
'general-max-failed-login-attempts-captcha' => 'MaxFailed.LoginAttempts.2ShowCaptcha',
|
||||
'openid-private-association-lifetime' => 'OpenId.Private.Association.Lifetime',
|
||||
'openid-session-association-lifetime' => 'OpenId.Session.Association.Lifetime',
|
||||
'openid-nonce-lifetime' => 'OpenId.Nonce.Lifetime',
|
||||
'oauth2-auth-code-lifetime' => 'OAuth2.AuthorizationCode.Lifetime',
|
||||
'oauth2-access-token-lifetime' => 'OAuth2.AccessToken.Lifetime',
|
||||
'oauth2-id-token-lifetime' => 'OAuth2.IdToken.Lifetime',
|
||||
'oauth2-refresh-token-lifetime' => 'OAuth2.RefreshToken.Lifetime',
|
||||
'oauth2-id-access-token-revoked-lifetime' => 'OAuth2.AccessToken.Revoked.Lifetime',
|
||||
'oauth2-id-access-token-void-lifetime' => 'OAuth2.AccessToken.Void.Lifetime',
|
||||
'oauth2-id-refresh-token-revoked-lifetime' => 'OAuth2.RefreshToken.Revoked.Lifetime',
|
||||
'oauth2-id-security-policy-minutes-without-exceptions' => 'OAuth2SecurityPolicy.MinutesWithoutExceptions',
|
||||
'oauth2-id-security-policy-max-bearer-token-disclosure-attempts' => 'OAuth2SecurityPolicy.MaxBearerTokenDisclosureAttempts',
|
||||
'oauth2-id-security-policy-max-invalid-client-exception-attempts' => 'OAuth2SecurityPolicy.MaxInvalidClientExceptionAttempts',
|
||||
'oauth2-id-security-policy-max-invalid-redeem-auth-code-attempts' => 'OAuth2SecurityPolicy.MaxInvalidRedeemAuthCodeAttempts',
|
||||
'oauth2-id-security-policy-max-invalid-client-credentials-attempts' => 'OAuth2SecurityPolicy.MaxInvalidClientCredentialsAttempts',
|
||||
);
|
||||
|
||||
// Creates a Validator instance and validates the data.
|
||||
$validation = Validator::make($values, $rules);
|
||||
|
||||
if ($validation->fails()) {
|
||||
if ($validation->fails())
|
||||
{
|
||||
return Redirect::action("AdminController@listServerConfig")->withErrors($validation);
|
||||
}
|
||||
|
||||
foreach($values as $field=>$value){
|
||||
if(array_key_exists($field,$dictionary))
|
||||
$this->configuration_service->saveConfigValue($dictionary[$field],$value);
|
||||
foreach($values as $field => $value)
|
||||
{
|
||||
if(array_key_exists($field, $dictionary))
|
||||
$this->configuration_service->saveConfigValue($dictionary[$field], $value);
|
||||
}
|
||||
|
||||
return Redirect::action("AdminController@listServerConfig");
|
||||
|
|
|
@ -240,6 +240,12 @@ class ValidateBearerTokenGrantType extends AbstractGrantType
|
|||
$this->log_service->error($ex2);
|
||||
throw new BearerTokenDisclosureAttemptException($ex2->getMessage());
|
||||
}
|
||||
catch(ExpiredAccessTokenException $ex3)
|
||||
{
|
||||
$this->log_service->error($ex3);
|
||||
$this->token_service->expireAccessToken($token_value);
|
||||
throw $ex3;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -22,7 +22,7 @@ interface IResourceServerService {
|
|||
* @param int $page_nbr
|
||||
* @return mixed
|
||||
*/
|
||||
public function getAll($page_nbr=1,$page_size=10,array $filters = array(), array $fields=array('*'));
|
||||
public function getAll($page_nbr = 1,$page_size = 10, array $filters = array(), array $fields=array('*'));
|
||||
|
||||
/**
|
||||
* @param IResourceServer $resource_server
|
||||
|
@ -71,4 +71,10 @@ interface IResourceServerService {
|
|||
* @return string
|
||||
*/
|
||||
public function regenerateClientSecret($id);
|
||||
|
||||
/**
|
||||
* @param string $ip
|
||||
* @return IResourceServer
|
||||
*/
|
||||
public function getByIPAddress($ip);
|
||||
}
|
|
@ -156,6 +156,13 @@ interface ITokenService {
|
|||
*/
|
||||
public function revokeAccessToken($value, $is_hashed = false);
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @param bool|false $is_hashed
|
||||
* @return bool
|
||||
*/
|
||||
public function expireAccessToken($value, $is_hashed = false);
|
||||
|
||||
/**
|
||||
* @param $value refresh_token value
|
||||
* @param bool $is_hashed
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace utils\services;
|
||||
use utils\exceptions\UnacquiredLockException;
|
||||
|
||||
use Closure;
|
||||
/**
|
||||
* Interface ILockManagerService
|
||||
* @package utils\services
|
||||
|
@ -14,6 +14,19 @@ interface ILockManagerService {
|
|||
* @throws UnacquiredLockException
|
||||
* @return mixed
|
||||
*/
|
||||
public function acquireLock($name,$lifetime=3600);
|
||||
public function acquireLock($name,$lifetime = 3600);
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function releaseLock($name);
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param Closure $callback
|
||||
* @param int $lifetime
|
||||
* @return mixed
|
||||
*/
|
||||
public function lock($name, Closure $callback, $lifetime = 3600);
|
||||
}
|
|
@ -5,7 +5,20 @@
|
|||
*/
|
||||
class AccessToken extends Eloquent {
|
||||
|
||||
protected $fillable = array('value','user_id', 'from_ip', 'associated_authorization_code','lifetime','scope','audience','created_at','updated_at','client_id','refresh_token_id');
|
||||
protected $fillable = array
|
||||
(
|
||||
'value',
|
||||
'user_id',
|
||||
'from_ip',
|
||||
'associated_authorization_code',
|
||||
'lifetime',
|
||||
'scope',
|
||||
'audience',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
'client_id',
|
||||
'refresh_token_id'
|
||||
);
|
||||
|
||||
protected $table = 'oauth2_access_token';
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ use utils\db\ITransactionService;
|
|||
* Class ResourceServerService
|
||||
* @package services\oauth2
|
||||
*/
|
||||
class ResourceServerService implements IResourceServerService
|
||||
final class ResourceServerService implements IResourceServerService
|
||||
{
|
||||
|
||||
private $client_service;
|
||||
|
@ -29,7 +29,7 @@ class ResourceServerService implements IResourceServerService
|
|||
public function __construct(IClientService $client_service, ITransactionService $tx_service)
|
||||
{
|
||||
$this->client_service = $client_service;
|
||||
$this->tx_service = $tx_service;
|
||||
$this->tx_service = $tx_service;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -186,6 +186,12 @@ class ResourceServerService implements IResourceServerService
|
|||
$host));
|
||||
}
|
||||
|
||||
if (ResourceServer::where('ip', '=', $ip)->count() > 0)
|
||||
{
|
||||
throw new InvalidResourceServer(sprintf('there is already another resource server with that ip (%s).',
|
||||
$ip));
|
||||
}
|
||||
|
||||
if (ResourceServer::where('friendly_name', '=', $friendly_name)->count() > 0) {
|
||||
throw new InvalidResourceServer(sprintf('there is already another resource server with that friendly name (%s).',
|
||||
$friendly_name));
|
||||
|
@ -245,4 +251,13 @@ class ResourceServerService implements IResourceServerService
|
|||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $ip
|
||||
* @return IResourceServer
|
||||
*/
|
||||
public function getByIPAddress($ip)
|
||||
{
|
||||
return ResourceServer::where('ip', '=', $ip)->first();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -772,7 +772,6 @@ final class TokenService implements ITokenService
|
|||
) {
|
||||
//hash the given value, bc tokens values are stored hashed on DB
|
||||
$hashed_value = !$is_hashed ? Hash::compute('sha256', $value) : $value;
|
||||
$lock_name = '';
|
||||
$access_token = null;
|
||||
|
||||
try
|
||||
|
@ -780,39 +779,33 @@ final class TokenService implements ITokenService
|
|||
// check cache ...
|
||||
if (!$cache_service->exists($hashed_value))
|
||||
{
|
||||
// check on DB...
|
||||
$access_token_db = DBAccessToken::where('value', '=', $hashed_value)->first();
|
||||
if (is_null($access_token_db))
|
||||
{
|
||||
if($this_var->isAccessTokenRevoked($hashed_value))
|
||||
$lock_manager_service->lock('lock.get.accesstoken.' . $hashed_value, function() use($value, $hashed_value, $this_var){
|
||||
// check on DB...
|
||||
$access_token_db = DBAccessToken::where('value', '=', $hashed_value)->first();
|
||||
if (is_null($access_token_db))
|
||||
{
|
||||
throw new RevokedAccessTokenException(sprintf('Access token %s is revoked!', $value));
|
||||
if($this_var->isAccessTokenRevoked($hashed_value))
|
||||
{
|
||||
throw new RevokedAccessTokenException(sprintf('Access token %s is revoked!', $value));
|
||||
}
|
||||
else if($this_var->isAccessTokenVoid($hashed_value)) // check if its marked on cache as expired ...
|
||||
{
|
||||
throw new ExpiredAccessTokenException(sprintf('Access token %s is expired!', $value));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidGrantTypeException(sprintf("Access token %s is invalid!", $value));
|
||||
}
|
||||
}
|
||||
else if($this_var->isAccessTokenVoid($hashed_value)) // check if its marked on cache as expired ...
|
||||
|
||||
if ($access_token_db->isVoid())
|
||||
{
|
||||
// invalid one ...
|
||||
throw new ExpiredAccessTokenException(sprintf('Access token %s is expired!', $value));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidGrantTypeException(sprintf("Access token %s is invalid!", $value));
|
||||
}
|
||||
}
|
||||
// lock ...
|
||||
$lock_name = 'lock.get.accesstoken.' . $hashed_value;
|
||||
$lock_manager_service->acquireLock($lock_name);
|
||||
if ($access_token_db->isVoid())
|
||||
{
|
||||
// invalid one ...
|
||||
// add to cache as expired ...
|
||||
$this_var->markAccessTokenAsVoid($hashed_value);
|
||||
// and deleted it from db
|
||||
$access_token_db->delete();
|
||||
throw new ExpiredAccessTokenException(sprintf('Access token %s is expired!', $value));
|
||||
}
|
||||
//reload on cache
|
||||
$this_var->storesDBAccessTokenOnCache($access_token_db);
|
||||
//release lock
|
||||
$lock_manager_service->releaseLock($lock_name);
|
||||
//reload on cache
|
||||
$this_var->storesDBAccessTokenOnCache($access_token_db);
|
||||
});
|
||||
}
|
||||
|
||||
$cache_values = $cache_service->getHash($hashed_value, array
|
||||
|
@ -861,19 +854,11 @@ final class TokenService implements ITokenService
|
|||
$refresh_token = $this_var->getRefreshToken($refresh_token_value, true);
|
||||
$access_token->setRefreshToken($refresh_token);
|
||||
}
|
||||
} catch (UnacquiredLockException $ex1) {
|
||||
throw new InvalidAccessTokenException("access token %s ", $value);
|
||||
} catch (ExpiredAccessTokenException $ex2) {
|
||||
if (!empty($lock_name)) {
|
||||
$lock_manager_service->releaseLock($lock_name);
|
||||
}
|
||||
} catch (\Exception $ex) {
|
||||
if (!empty($lock_name)) {
|
||||
$lock_manager_service->releaseLock($lock_name);
|
||||
}
|
||||
throw $ex;
|
||||
}
|
||||
|
||||
catch (UnacquiredLockException $ex1)
|
||||
{
|
||||
throw new InvalidAccessTokenException("access token %s ", $value);
|
||||
}
|
||||
return $access_token;
|
||||
});
|
||||
}
|
||||
|
@ -1080,6 +1065,7 @@ final class TokenService implements ITokenService
|
|||
$hashed_value = !$is_hashed ? Hash::compute('sha256', $value) : $value;
|
||||
|
||||
$access_token_db = DBAccessToken::where('value', '=', $hashed_value)->first();
|
||||
if(is_null($access_token_db)) return false;
|
||||
$client = $access_token_db->client()->first();
|
||||
//delete from cache
|
||||
$res = $cache_service->delete($hashed_value);
|
||||
|
@ -1099,6 +1085,41 @@ final class TokenService implements ITokenService
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @param bool|false $is_hashed
|
||||
* @return bool
|
||||
*/
|
||||
public function expireAccessToken($value, $is_hashed = false)
|
||||
{
|
||||
$cache_service = $this->cache_service;
|
||||
$this_var = $this;
|
||||
|
||||
return $this->tx_service->transaction(function () use ($value, $is_hashed, $cache_service, $this_var) {
|
||||
$res = 0;
|
||||
//hash the given value, bc tokens values are stored hashed on DB
|
||||
$hashed_value = !$is_hashed ? Hash::compute('sha256', $value) : $value;
|
||||
|
||||
$access_token_db = DBAccessToken::where('value', '=', $hashed_value)->first();
|
||||
if(is_null($access_token_db)) return false;
|
||||
$client = $access_token_db->client()->first();
|
||||
//delete from cache
|
||||
$res = $cache_service->delete($hashed_value);
|
||||
$res = $cache_service->deleteMemberSet
|
||||
(
|
||||
$client->client_id . TokenService::ClientAccessTokenPrefixList,
|
||||
$access_token_db->value
|
||||
);
|
||||
|
||||
//check on DB... and delete it
|
||||
$res = $access_token_db->delete();
|
||||
|
||||
$this_var->markAccessTokenAsVoid($hashed_value);
|
||||
|
||||
return $res > 0;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Revokes all related tokens to a specific client id
|
||||
* @param $client_id
|
||||
|
@ -1587,4 +1608,5 @@ final class TokenService implements ITokenService
|
|||
if(is_null($db_access_token)) return null;
|
||||
return $this->getAccessToken($db_access_token->value, true);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,17 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace services\openid;
|
||||
|
||||
use openid\exceptions\InvalidAssociation;
|
||||
use openid\exceptions\OpenIdInvalidRealmException;
|
||||
use openid\exceptions\ReplayAttackException;
|
||||
use openid\exceptions\InvalidAssociation;
|
||||
use openid\helpers\OpenIdErrorMessages;
|
||||
use openid\model\IAssociation;
|
||||
use openid\repositories\IOpenIdAssociationRepository;
|
||||
use openid\services\IAssociationService;
|
||||
use OpenIdAssociation;
|
||||
use utils\exceptions\UnacquiredLockException;
|
||||
use utils\services\ILockManagerService;
|
||||
use utils\services\ICacheService;
|
||||
use openid\repositories\IOpenIdAssociationRepository;
|
||||
use utils\services\ILockManagerService;
|
||||
|
||||
/**
|
||||
* Class AssociationService
|
||||
|
@ -22,20 +23,21 @@ class AssociationService implements IAssociationService
|
|||
|
||||
private $lock_manager_service;
|
||||
private $cache_service;
|
||||
private $repository;
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* @param IOpenIdAssociationRepository $repository
|
||||
* @param ILockManagerService $lock_manager_service
|
||||
* @param ICacheService $cache_service
|
||||
*/
|
||||
public function __construct(IOpenIdAssociationRepository $repository,
|
||||
ILockManagerService $lock_manager_service,
|
||||
ICacheService $cache_service)
|
||||
{
|
||||
/**
|
||||
* @param IOpenIdAssociationRepository $repository
|
||||
* @param ILockManagerService $lock_manager_service
|
||||
* @param ICacheService $cache_service
|
||||
*/
|
||||
public function __construct(
|
||||
IOpenIdAssociationRepository $repository,
|
||||
ILockManagerService $lock_manager_service,
|
||||
ICacheService $cache_service
|
||||
) {
|
||||
$this->lock_manager_service = $lock_manager_service;
|
||||
$this->cache_service = $cache_service;
|
||||
$this->repository = $repository;
|
||||
$this->cache_service = $cache_service;
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -58,26 +60,29 @@ class AssociationService implements IAssociationService
|
|||
if (!$this->cache_service->exists($handle)) {
|
||||
// if not , check on db
|
||||
$assoc = $this->repository->getByHandle($handle);
|
||||
if(is_null($assoc))
|
||||
throw new InvalidAssociation(sprintf('openid association %s does not exists!',$handle));
|
||||
if (is_null($assoc)) {
|
||||
throw new InvalidAssociation(sprintf('openid association %s does not exists!', $handle));
|
||||
}
|
||||
//check association lifetime ...
|
||||
$remaining_lifetime = $assoc->getRemainingLifetime();
|
||||
if ($remaining_lifetime < 0) {
|
||||
$this->deleteAssociation($handle);
|
||||
|
||||
return null;
|
||||
}
|
||||
//convert secret to hexa representation
|
||||
// bin2hex
|
||||
$secret_unpack = \unpack('H*', $assoc->secret);
|
||||
$secret_unpack = array_shift($secret_unpack);
|
||||
//convert secret to hexa representation
|
||||
// bin2hex
|
||||
$secret_unpack = \unpack('H*', $assoc->secret);
|
||||
$secret_unpack = array_shift($secret_unpack);
|
||||
//repopulate cache
|
||||
$this->cache_service->storeHash($handle, array(
|
||||
"type" => $assoc->type,
|
||||
"type" => $assoc->type,
|
||||
"mac_function" => $assoc->mac_function,
|
||||
"issued" => $assoc->issued,
|
||||
"lifetime" => $assoc->lifetime,
|
||||
"secret" => $secret_unpack,
|
||||
"realm" => $assoc->realm),
|
||||
"issued" => $assoc->issued,
|
||||
"lifetime" => $assoc->lifetime,
|
||||
"secret" => $secret_unpack,
|
||||
"realm" => $assoc->realm
|
||||
),
|
||||
$remaining_lifetime);
|
||||
}
|
||||
|
||||
|
@ -88,32 +93,37 @@ class AssociationService implements IAssociationService
|
|||
"issued",
|
||||
"lifetime",
|
||||
"secret",
|
||||
"realm"));
|
||||
"realm"
|
||||
));
|
||||
|
||||
if ($cache_values['type'] == IAssociation::TypePrivate) {
|
||||
if (is_null($realm) || empty($realm) || $cache_values['realm'] != $realm) {
|
||||
throw new OpenIdInvalidRealmException(sprintf(OpenIdErrorMessages::InvalidPrivateAssociationMessage, $handle, $realm));
|
||||
throw new OpenIdInvalidRealmException(sprintf(OpenIdErrorMessages::InvalidPrivateAssociationMessage,
|
||||
$handle, $realm));
|
||||
}
|
||||
// only one time we could use this handle
|
||||
$this->lock_manager_service->acquireLock($lock_name);
|
||||
}
|
||||
|
||||
//convert hex 2 bin
|
||||
$secret = \pack('H*', $cache_values['secret']);
|
||||
$assoc = new OpenIdAssociation();
|
||||
//convert hex 2 bin
|
||||
$secret = \pack('H*', $cache_values['secret']);
|
||||
$assoc = new OpenIdAssociation();
|
||||
|
||||
$assoc->type = $cache_values['type'];
|
||||
$assoc->type = $cache_values['type'];
|
||||
$assoc->mac_function = $cache_values['mac_function'];
|
||||
$assoc->issued = $cache_values['issued'];
|
||||
$assoc->lifetime = intval($cache_values['lifetime']);
|
||||
$assoc->secret = $secret;
|
||||
$realm = $cache_values['realm'];
|
||||
if (!empty($realm))
|
||||
$assoc->issued = $cache_values['issued'];
|
||||
$assoc->lifetime = intval($cache_values['lifetime']);
|
||||
$assoc->secret = $secret;
|
||||
$realm = $cache_values['realm'];
|
||||
if (!empty($realm)) {
|
||||
$assoc->realm = $realm;
|
||||
}
|
||||
|
||||
return $assoc;
|
||||
|
||||
} catch (UnacquiredLockException $ex1) {
|
||||
throw new ReplayAttackException(sprintf(OpenIdErrorMessages::ReplayAttackPrivateAssociationAlreadyUsed, $handle));
|
||||
throw new ReplayAttackException(sprintf(OpenIdErrorMessages::ReplayAttackPrivateAssociationAlreadyUsed,
|
||||
$handle));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,57 +135,61 @@ class AssociationService implements IAssociationService
|
|||
{
|
||||
$this->cache_service->delete($handle);
|
||||
$assoc = $this->repository->getByHandle($handle);
|
||||
if (!is_null($assoc)) {
|
||||
if (!is_null($assoc)) {
|
||||
return $this->repository->delete($assoc);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param IAssociation $association
|
||||
* @return IAssociation|OpenIdAssociation
|
||||
* @throws \openid\exceptions\ReplayAttackException
|
||||
*/
|
||||
public function addAssociation(IAssociation $association)
|
||||
/**
|
||||
* @param IAssociation $association
|
||||
* @return IAssociation|OpenIdAssociation
|
||||
* @throws \openid\exceptions\ReplayAttackException
|
||||
*/
|
||||
public function addAssociation(IAssociation $association)
|
||||
{
|
||||
$assoc = new OpenIdAssociation();
|
||||
try {
|
||||
$lock_name = 'lock.add.assoc.' . $association->getHandle();
|
||||
$this->lock_manager_service->acquireLock($lock_name);
|
||||
|
||||
$assoc->identifier = $association->getHandle();;
|
||||
$assoc->secret = $association->getSecret();
|
||||
$assoc->type = $association->getType();;
|
||||
$assoc->identifier = $association->getHandle();;
|
||||
$assoc->secret = $association->getSecret();
|
||||
$assoc->type = $association->getType();;
|
||||
$assoc->mac_function = $association->getMacFunction();
|
||||
$assoc->lifetime = intval($association->getLifetime());
|
||||
$assoc->issued = $association->getIssued();
|
||||
$assoc->lifetime = intval($association->getLifetime());
|
||||
$assoc->issued = $association->getIssued();
|
||||
|
||||
if (!is_null($association->getRealm()))
|
||||
if (!is_null($association->getRealm())) {
|
||||
$assoc->realm = $association->getRealm();
|
||||
}
|
||||
|
||||
if ($association->getType() == IAssociation::TypeSession) {
|
||||
$this->repository->add($assoc);
|
||||
}
|
||||
//convert secret to hexa representation
|
||||
// bin2hex
|
||||
$secret_unpack = \unpack('H*', $association->getSecret());
|
||||
$secret_unpack = array_shift($secret_unpack);
|
||||
//convert secret to hexa representation
|
||||
// bin2hex
|
||||
$secret_unpack = \unpack('H*', $association->getSecret());
|
||||
$secret_unpack = array_shift($secret_unpack);
|
||||
|
||||
$this->cache_service->storeHash($association->getHandle(),
|
||||
array(
|
||||
"type" => $association->getType(),
|
||||
"mac_function" => $association->getMacFunction(),
|
||||
"issued" => $association->getIssued(),
|
||||
"lifetime" => intval($association->getLifetime()),
|
||||
"secret" => $secret_unpack,
|
||||
"realm" => !is_null($association->getRealm())?$association->getRealm():''
|
||||
),
|
||||
intval($association->getLifetime())
|
||||
array(
|
||||
"type" => $association->getType(),
|
||||
"mac_function" => $association->getMacFunction(),
|
||||
"issued" => $association->getIssued(),
|
||||
"lifetime" => intval($association->getLifetime()),
|
||||
"secret" => $secret_unpack,
|
||||
"realm" => !is_null($association->getRealm()) ? $association->getRealm() : ''
|
||||
),
|
||||
intval($association->getLifetime())
|
||||
);
|
||||
|
||||
} catch (UnacquiredLockException $ex1) {
|
||||
throw new ReplayAttackException(sprintf(OpenIdErrorMessages::ReplayAttackPrivateAssociationAlreadyUsed, $association->getHandle()));
|
||||
throw new ReplayAttackException(sprintf(OpenIdErrorMessages::ReplayAttackPrivateAssociationAlreadyUsed,
|
||||
$association->getHandle()));
|
||||
}
|
||||
|
||||
return $assoc;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ use DateTime;
|
|||
use DB;
|
||||
use Exception;
|
||||
use Log;
|
||||
use oauth2\services\IResourceServerService;
|
||||
use UserExceptionTrail;
|
||||
use utils\db\ITransactionService;
|
||||
use utils\exceptions\UnacquiredLockException;
|
||||
|
@ -23,21 +24,34 @@ use utils\services\IServerConfigurationService;
|
|||
class BlacklistSecurityPolicy extends AbstractBlacklistSecurityPolicy
|
||||
{
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $exception_dictionary = array();
|
||||
|
||||
/**
|
||||
* @var IResourceServerService
|
||||
*/
|
||||
private $resource_server_service;
|
||||
|
||||
/**
|
||||
* BlacklistSecurityPolicy constructor.
|
||||
* @param IServerConfigurationService $server_configuration_service
|
||||
* @param ILockManagerService $lock_manager_service
|
||||
* @param ICacheService $cache_service
|
||||
* @param IResourceServerService $resource_server_service
|
||||
* @param ITransactionService $tx_service
|
||||
*/
|
||||
public function __construct(
|
||||
public function __construct
|
||||
(
|
||||
IServerConfigurationService $server_configuration_service,
|
||||
ILockManagerService $lock_manager_service,
|
||||
ICacheService $cache_service,
|
||||
ITransactionService $tx_service
|
||||
ILockManagerService $lock_manager_service,
|
||||
ICacheService $cache_service,
|
||||
IResourceServerService $resource_server_service,
|
||||
ITransactionService $tx_service
|
||||
) {
|
||||
parent::__construct($server_configuration_service, $lock_manager_service, $cache_service, $tx_service);
|
||||
$this->resource_server_service = $resource_server_service;
|
||||
// here we configure on which exceptions are we interested and the max occurrence attempts and initial delay on tar pit for
|
||||
// offending IP address
|
||||
$this->exception_dictionary = array(
|
||||
|
@ -94,13 +108,12 @@ class BlacklistSecurityPolicy extends AbstractBlacklistSecurityPolicy
|
|||
*/
|
||||
public function check()
|
||||
{
|
||||
$res = true;
|
||||
$res = true;
|
||||
$remote_address = IPHelper::getUserIp();
|
||||
try {
|
||||
//check if banned ip is on cache ...
|
||||
if ($this->cache_service->incCounterIfExists($remote_address)) {
|
||||
$this->counter_measure->trigger();
|
||||
|
||||
return false;
|
||||
}
|
||||
//check on db
|
||||
|
@ -155,14 +168,16 @@ class BlacklistSecurityPolicy extends AbstractBlacklistSecurityPolicy
|
|||
{
|
||||
try
|
||||
{
|
||||
$remote_ip = IPHelper::getUserIp();
|
||||
$remote_ip = IPHelper::getUserIp();
|
||||
$exception_class = get_class($ex);
|
||||
|
||||
//check exception count by type on last "MinutesWithoutExceptions" minutes...
|
||||
$exception_count = intval(UserExceptionTrail::where('from_ip', '=', $remote_ip)
|
||||
->where('exception_type', '=', $exception_class)
|
||||
->where('created_at', '>',
|
||||
DB::raw('( UTC_TIMESTAMP() - INTERVAL ' . $this->server_configuration_service->getConfigValue("BlacklistSecurityPolicy.MinutesWithoutExceptions") . ' MINUTE )'))
|
||||
->count());
|
||||
|
||||
if (array_key_exists($exception_class, $this->exception_dictionary))
|
||||
{
|
||||
$params = $this->exception_dictionary[$exception_class];
|
||||
|
@ -181,7 +196,7 @@ class BlacklistSecurityPolicy extends AbstractBlacklistSecurityPolicy
|
|||
);
|
||||
|
||||
$initial_delay_on_tar_pit = intval($this->server_configuration_service->getConfigValue($params[1]));
|
||||
if ($exception_count >= $max_attempts)
|
||||
if ($exception_count >= $max_attempts && !$this->isIPAddressWhitelisted($remote_ip))
|
||||
{
|
||||
Log::warning
|
||||
(
|
||||
|
@ -206,6 +221,16 @@ class BlacklistSecurityPolicy extends AbstractBlacklistSecurityPolicy
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $ip
|
||||
* @return bool
|
||||
*/
|
||||
private function isIPAddressWhitelisted($ip)
|
||||
{
|
||||
$rs = $this->resource_server_service->getByIPAddress($ip);
|
||||
return !is_null($rs);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ class OAuth2SecurityPolicy implements ISecurityPolicy{
|
|||
'auth2\exceptions\BearerTokenDisclosureAttemptException' => array('OAuth2SecurityPolicy.MaxBearerTokenDisclosureAttempts'),
|
||||
'auth2\exceptions\InvalidClientException' => array('OAuth2SecurityPolicy.MaxInvalidClientExceptionAttempts'),
|
||||
'auth2\exceptions\InvalidRedeemAuthCodeException' => array('OAuth2SecurityPolicy.MaxInvalidRedeemAuthCodeAttempts'),
|
||||
'auth2\exceptions\InvalidClientCredentials' => array('OAuth2SecurityPolicy.MaxInvalidInvalidClientCredentialsAttempts'),
|
||||
'auth2\exceptions\InvalidClientCredentials' => array('OAuth2SecurityPolicy.MaxInvalidClientCredentialsAttempts'),
|
||||
);
|
||||
}
|
||||
/**
|
||||
|
|
|
@ -5,25 +5,78 @@ namespace services\utils;
|
|||
use utils\services\ICacheService;
|
||||
use utils\services\ILockManagerService;
|
||||
use utils\exceptions\UnacquiredLockException;
|
||||
use Closure;
|
||||
|
||||
class LockManagerService implements ILockManagerService {
|
||||
/**
|
||||
* Class LockManagerService
|
||||
* @package services\utils
|
||||
*/
|
||||
final class LockManagerService implements ILockManagerService {
|
||||
|
||||
/**
|
||||
* @var ICacheService
|
||||
*/
|
||||
private $cache_service;
|
||||
|
||||
/**
|
||||
* LockManagerService constructor.
|
||||
* @param ICacheService $cache_service
|
||||
*/
|
||||
public function __construct(ICacheService $cache_service){
|
||||
$this->cache_service = $cache_service;
|
||||
}
|
||||
|
||||
public function acquireLock($name,$lifetime=3600)
|
||||
/**
|
||||
* @param string $name
|
||||
* @param int $lifetime
|
||||
* @throws UnacquiredLockException
|
||||
*/
|
||||
public function acquireLock($name,$lifetime = 3600)
|
||||
{
|
||||
$success = $this->cache_service->addSingleValue($name,time()+$lifetime+1,time()+$lifetime+1);
|
||||
if (!$success) { // only one time we could use this handle
|
||||
$time = time()+$lifetime+1;
|
||||
$success = $this->cache_service->addSingleValue($name, $time, $time);
|
||||
if (!$success)
|
||||
{
|
||||
// only one time we could use this handle
|
||||
throw new UnacquiredLockException(sprintf("lock name %s",$name));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*/
|
||||
public function releaseLock($name)
|
||||
{
|
||||
$this->cache_service->delete($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param Closure $callback
|
||||
* @param int $lifetime
|
||||
* @return null
|
||||
* @throws UnacquiredLockException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function lock($name, Closure $callback, $lifetime = 3600)
|
||||
{
|
||||
$result = null;
|
||||
|
||||
try
|
||||
{
|
||||
$this->acquireLock($name, $lifetime);
|
||||
$result = $callback($this);
|
||||
$this->releaseLock($name);
|
||||
}
|
||||
catch(UnacquiredLockException $ex1)
|
||||
{
|
||||
throw $ex1;
|
||||
}
|
||||
catch(\Exception $ex)
|
||||
{
|
||||
$this->releaseLock($name);
|
||||
throw $ex;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
|
@ -109,36 +109,24 @@ class ServerConfigurationService implements IOpenIdServerConfigurationService, I
|
|||
10);
|
||||
|
||||
|
||||
$this->default_config_params["OAuth2.AuthorizationCode.Lifetime"] = Config::get('server.OAuth2_AuthorizationCode_Lifetime',
|
||||
240);
|
||||
$this->default_config_params["OAuth2.AccessToken.Lifetime"] = Config::get('server.OAuth2_AccessToken_Lifetime',
|
||||
3600);
|
||||
|
||||
$this->default_config_params["OAuth2.IdToken.Lifetime"] = Config::get('server.OAuth2_IdToken_Lifetime',
|
||||
3600);
|
||||
$this->default_config_params["OAuth2.AuthorizationCode.Lifetime"] = Config::get('server.OAuth2_AuthorizationCode_Lifetime', 240);
|
||||
$this->default_config_params["OAuth2.AccessToken.Lifetime"] = Config::get('server.OAuth2_AccessToken_Lifetime', 3600);
|
||||
$this->default_config_params["OAuth2.IdToken.Lifetime"] = Config::get('server.OAuth2_IdToken_Lifetime', 3600);
|
||||
//infinite by default
|
||||
$this->default_config_params["OAuth2.RefreshToken.Lifetime"] = Config::get('server.OAuth2_RefreshToken_Lifetime',
|
||||
0);
|
||||
|
||||
$this->default_config_params["OAuth2.AccessToken.Revoked.Lifetime"] = Config::get('server.OAuth2_AccessToken_Revoked_Lifetime', 600);
|
||||
$this->default_config_params["OAuth2.AccessToken.Void.Lifetime"] = Config::get('server.OAuth2_AccessToken_Void_Lifetime', 600);
|
||||
$this->default_config_params["OAuth2.RefreshToken.Revoked.Lifetime"] = Config::get('server.OAuth2_RefreshToken_Revoked_Lifetime', 600);
|
||||
$this->default_config_params["OAuth2.RefreshToken.Lifetime"] = Config::get('server.OAuth2_RefreshToken_Lifetime', 0);
|
||||
//revoked lifetimes
|
||||
$this->default_config_params["OAuth2.AccessToken.Revoked.Lifetime"] = Config::get('server.OAuth2_AccessToken_Revoked_Lifetime', 3600);
|
||||
$this->default_config_params["OAuth2.AccessToken.Void.Lifetime"] = Config::get('server.OAuth2_AccessToken_Void_Lifetime', 3600);
|
||||
$this->default_config_params["OAuth2.RefreshToken.Revoked.Lifetime"] = Config::get('server.OAuth2_RefreshToken_Revoked_Lifetime', 3600);
|
||||
|
||||
//oauth2 policy defaults
|
||||
$this->default_config_params["OAuth2SecurityPolicy.MinutesWithoutExceptions"] = Config::get('server.OAuth2SecurityPolicy_MinutesWithoutExceptions',
|
||||
2);
|
||||
$this->default_config_params["OAuth2SecurityPolicy.MaxBearerTokenDisclosureAttempts"] = Config::get('server.OAuth2SecurityPolicy_MaxBearerTokenDisclosureAttempts',
|
||||
5);
|
||||
$this->default_config_params["OAuth2SecurityPolicy.MaxInvalidClientExceptionAttempts"] = Config::get('server.OAuth2SecurityPolicy_MaxInvalidClientExceptionAttempts',
|
||||
10);
|
||||
$this->default_config_params["OAuth2SecurityPolicy.MaxInvalidRedeemAuthCodeAttempts"] = Config::get('server.OAuth2SecurityPolicy_MaxInvalidRedeemAuthCodeAttempts',
|
||||
10);
|
||||
$this->default_config_params["OAuth2SecurityPolicy.MaxInvalidInvalidClientCredentialsAttempts"] = Config::get('server.OAuth2SecurityPolicy_MaxInvalidInvalidClientCredentialsAttempts',
|
||||
5);
|
||||
|
||||
$this->default_config_params["OAuth2SecurityPolicy.MinutesWithoutExceptions"] = Config::get('server.OAuth2SecurityPolicy_MinutesWithoutExceptions', 2);
|
||||
$this->default_config_params["OAuth2SecurityPolicy.MaxBearerTokenDisclosureAttempts"] = Config::get('server.OAuth2SecurityPolicy_MaxBearerTokenDisclosureAttempts', 5);
|
||||
$this->default_config_params["OAuth2SecurityPolicy.MaxInvalidClientExceptionAttempts"] = Config::get('server.OAuth2SecurityPolicy_MaxInvalidClientExceptionAttempts', 10);
|
||||
$this->default_config_params["OAuth2SecurityPolicy.MaxInvalidRedeemAuthCodeAttempts"] = Config::get('server.OAuth2SecurityPolicy_MaxInvalidRedeemAuthCodeAttempts', 10);
|
||||
$this->default_config_params["OAuth2SecurityPolicy.MaxInvalidClientCredentialsAttempts"] = Config::get('server.OAuth2SecurityPolicy_MaxInvalidClientCredentialsAttempts', 5);
|
||||
//ssl
|
||||
$this->default_config_params["SSL.Enable"] = Config::get('server.SSL_Enable', true);
|
||||
|
||||
}
|
||||
|
||||
public function getUserIdentityEndpointURL($identifier)
|
||||
|
|
|
@ -48,6 +48,40 @@
|
|||
<label for="oauth2-refresh-token-lifetime">Refresh Token Lifetime <span class="glyphicon glyphicon-info-sign accordion-toggle" aria-hidden="true" title="in seconds - zero value means infinite"></span></label>
|
||||
<input class="form-control" type="number" min="0" step="1" id="oauth2-refresh-token-lifetime" name="oauth2-refresh-token-lifetime" value="{{$config_values['OAuth2.RefreshToken.Lifetime']}}"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="oauth2-id-access-token-revoked-lifetime">Revoked Access Token Lifetime <span class="glyphicon glyphicon-info-sign accordion-toggle" aria-hidden="true" title="in seconds"></span></label>
|
||||
<input class="form-control" type="number" min="600" step="1" id="oauth2-id-access-token-revoked-lifetime" name="oauth2-id-access-token-revoked-lifetime" value="{{$config_values['OAuth2.AccessToken.Revoked.Lifetime']}}"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="oauth2-id-access-token-void-lifetime">Void Access Token Lifetime <span class="glyphicon glyphicon-info-sign accordion-toggle" aria-hidden="true" title="in seconds"></span></label>
|
||||
<input class="form-control" type="number" min="600" step="1" id="oauth2-id-access-token-void-lifetime" name="oauth2-id-access-token-void-lifetime" value="{{$config_values['OAuth2.AccessToken.Void.Lifetime']}}"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="oauth2-id-refresh-token-revoked-lifetime">Revoked Refresh Token Lifetime <span class="glyphicon glyphicon-info-sign accordion-toggle" aria-hidden="true" title="in seconds"></span></label>
|
||||
<input class="form-control" type="number" min="600" step="1" id="oauth2-id-refresh-token-revoked-lifetime" name="oauth2-id-refresh-token-revoked-lifetime" value="{{$config_values['OAuth2.RefreshToken.Revoked.Lifetime']}}"/>
|
||||
</div>
|
||||
<legend>OAUTH2 Security Policies Configuration</legend>
|
||||
<div class="form-group">
|
||||
<label for="oauth2-id-security-policy-minutes-without-exceptions">Minutes without exceptions rate <span class="glyphicon glyphicon-info-sign accordion-toggle" aria-hidden="true" title="in minutes"></span></label>
|
||||
<input class="form-control" type="number" min="1" step="1" id="oauth2-id-security-policy-minutes-without-exceptions" name="oauth2-id-security-policy-minutes-without-exceptions" value="{{$config_values['OAuth2SecurityPolicy.MinutesWithoutExceptions']}}"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="oauth2-id-security-policy-max-bearer-token-disclosure-attempts">Max. Bearer token disclousure exceptions attemps <span class="glyphicon glyphicon-info-sign accordion-toggle" aria-hidden="true" title="in attemps"></span></label>
|
||||
<input class="form-control" type="number" min="3" step="1" id="oauth2-id-security-policy-max-bearer-token-disclosure-attempts" name="oauth2-id-security-policy-max-bearer-token-disclosure-attempts" value="{{$config_values['OAuth2SecurityPolicy.MaxBearerTokenDisclosureAttempts']}}"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="oauth2-id-security-policy-max-invalid-client-exception-attempts">Max. invalid client exception attemps <span class="glyphicon glyphicon-info-sign accordion-toggle" aria-hidden="true" title="in attemps"></span></label>
|
||||
<input class="form-control" type="number" min="3" step="1" id="oauth2-id-security-policy-max-invalid-client-exception-attempts" name="oauth2-id-security-policy-max-invalid-client-exception-attempts" value="{{$config_values['OAuth2SecurityPolicy.MaxInvalidClientExceptionAttempts']}}"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="oauth2-id-security-policy-max-invalid-redeem-auth-code-attempts">Max. invalid redeem Auth Code exception attemps <span class="glyphicon glyphicon-info-sign accordion-toggle" aria-hidden="true" title="in attemps"></span></label>
|
||||
<input class="form-control" type="number" min="3" step="1" id="oauth2-id-security-policy-max-invalid-redeem-auth-code-attempts" name="oauth2-id-security-policy-max-invalid-redeem-auth-code-attempts" value="{{$config_values['OAuth2SecurityPolicy.MaxInvalidRedeemAuthCodeAttempts']}}"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="oauth2-id-security-policy-max-invalid-client-credentials-attempts">Max. invalid client credentials exception attemps <span class="glyphicon glyphicon-info-sign accordion-toggle" aria-hidden="true" title="in attemps"></span></label>
|
||||
<input class="form-control" type="number" min="3" step="1" id="oauth2-id-security-policy-max-invalid-client-credentials-attempts" name="oauth2-id-security-policy-max-invalid-client-credentials-attempts" value="{{$config_values['OAuth2SecurityPolicy.MaxInvalidClientCredentialsAttempts']}}"/>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-default btn-md active">Submit</button>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -6,15 +6,23 @@ jQuery(document).ready(function($){
|
|||
|
||||
var server_config_validation = form_server_config.validate({
|
||||
rules: {
|
||||
"general-max-failed-login-attempts" : {required: true, number: true },
|
||||
"general-max-failed-login-attempts-captcha" : {required: true, number: true },
|
||||
"openid-private-association-lifetime" : {required: true, number: true },
|
||||
"openid-session-association-lifetime" : {required: true, number: true },
|
||||
"openid-nonce-lifetime" : {required: true, number: true },
|
||||
"oauth2-auth-code-lifetime" : {required: true, number: true },
|
||||
"oauth2-refresh-token-lifetime" : {required: true, number: true },
|
||||
"oauth2-access-token-lifetime" : {required: true, number: true },
|
||||
"oauth2-id-token-lifetime" : {required: true, number: true }
|
||||
"general-max-failed-login-attempts" : {required: true, number: true },
|
||||
"general-max-failed-login-attempts-captcha" : {required: true, number: true },
|
||||
"openid-private-association-lifetime" : {required: true, number: true },
|
||||
"openid-session-association-lifetime" : {required: true, number: true },
|
||||
"openid-nonce-lifetime" : {required: true, number: true },
|
||||
"oauth2-auth-code-lifetime" : {required: true, number: true },
|
||||
"oauth2-refresh-token-lifetime" : {required: true, number: true },
|
||||
"oauth2-access-token-lifetime" : {required: true, number: true },
|
||||
"oauth2-id-token-lifetime" : {required: true, number: true },
|
||||
"oauth2-id-access-token-revoked-lifetime" : {required: true, number: true },
|
||||
"oauth2-id-access-token-void-lifetime" : {required: true, number: true },
|
||||
"oauth2-id-refresh-token-revoked-lifetime" : {required: true, number: true },
|
||||
"oauth2-id-security-policy-minutes-without-exceptions" : {required: true, number: true },
|
||||
"oauth2-id-security-policy-max-bearer-token-disclosure-attempts" : {required: true, number: true },
|
||||
"oauth2-id-security-policy-max-invalid-client-exception-attempts" : {required: true, number: true },
|
||||
"oauth2-id-security-policy-max-invalid-redeem-auth-code-attempts" : {required: true, number: true },
|
||||
"oauth2-id-security-policy-max-invalid-client-credentials-attempts" : {required: true, number: true },
|
||||
}
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue