/** * Adds the passed principal to the group. * * @param \AppserverIo\Psr\Security\PrincipalInterface $pricipal The principal to add * * @return boolean TRUE if the member was successfully added, FALSE if the principal was already a member */ public function addMember(PrincipalInterface $pricipal) { // query whether or not the passed prinicpal is already a member $isMember = $this->members->exists($pricipal->getName()); // if the principal is not a member, add it if ($isMember === false) { $this->members->add($pricipal->getName(), $pricipal); } // return if the principal has successfully been added return $isMember === false; }
/** * The main method that creates new instances in a separate context. * * @param \AppserverIo\Psr\Application\ApplicationInterface $application The application instance to register the class loader with * @param \AppserverIo\Appserver\Core\Api\Node\ManagerNodeInterface $managerConfiguration The manager configuration * * @return void */ public static function visit(ApplicationInterface $application, ManagerNodeInterface $managerConfiguration) { // initialize the sessions and the session settings $sessionHandlers = new HashMap(); $sessionSettings = new DefaultSessionSettings(); $sessionMarshaller = new StandardSessionMarshaller(); // add the configured session handlers /** @var \AppserverIo\Appserver\Core\Api\Node\SessionHandlerNode $sessionHandlerNode */ foreach ($managerConfiguration->getSessionHandlers() as $sessionHandlerNode) { if ($factory = $sessionHandlerNode->getFactory()) { $sessionHandlers->add($sessionHandlerNode->getName(), $factory::create($sessionHandlerNode, $sessionSettings, $sessionMarshaller)); } } // we need a garbage collector $garbageCollector = new StandardGarbageCollector(); $garbageCollector->injectApplication($application); $garbageCollector->injectSessionSettings($sessionSettings); $garbageCollector->start(); // and finally we need the session manager instance $sessionManager = new StandardSessionManager(); $sessionManager->injectApplication($application); $sessionManager->injectSessionSettings($sessionSettings); $sessionManager->injectSessionHandlers($sessionHandlers); $sessionManager->injectGarbageCollector($garbageCollector); $sessionManager->injectSessionMarshaller($sessionMarshaller); $sessionManager->injectManagerConfiguration($managerConfiguration); // attach the instance $application->addManager($sessionManager, $managerConfiguration); }
/** * Execute the rolesQuery against the dsJndiName to obtain the roles for the authenticated user. * * @param \AppserverIo\Lang\String $username The username to load the roles for * @param \AppserverIo\Lang\String $lookupName The lookup name for the datasource * @param \AppserverIo\Lang\String $rolesQuery The query to load the roles * @param \AppserverIo\Psr\Spi\LoginModuleInterface $aslm The login module to add the roles to * * @return array An array of groups containing the sets of roles * @throws \AppserverIo\Appserver\ServletEngine\Security\Logi\LoginException Is thrown if an error during login occured */ public static function getRoleSets(string $username, string $lookupName, string $rolesQuery, LoginModuleInterface $aslm) { try { // initialize the map for the groups $setsMap = new HashMap(); // load the application context $application = RequestHandler::getApplicationContext(); /** @var \AppserverIo\Appserver\Core\Api\Node\DatabaseNode $databaseNode */ $databaseNode = $application->getNamingDirectory()->search($lookupName)->getDatabase(); // prepare the connection parameters and create the DBAL connection $connection = DriverManager::getConnection(ConnectionUtil::get($application)->fromDatabaseNode($databaseNode)); // try to load the principal's roles from the database $statement = $connection->prepare($rolesQuery); $statement->bindParam(1, $username); $statement->execute(); // query whether or not we've a password found or not $row = $statement->fetch(\PDO::FETCH_NUM); // query whether or not we've found at least one role if ($row == false) { // try load the unauthenticated identity if ($aslm->getUnauthenticatedIdentity() == null) { throw new FailedLoginException('No matching username found in Roles'); } // we're running with an unauthenticatedIdentity so create an empty roles set and return return array(new SimpleGroup(Util::DEFAULT_GROUP_NAME)); } do { // load the found name and initialize the group name with a default value $name = $row[0]; $groupName = Util::DEFAULT_GROUP_NAME; // query whether or not we've to initialize a default group if (isset($row[1])) { $groupName = $row[1]; } // query whether or not the group already exists in the set if ($setsMap->exists($groupName) === false) { $group = new SimpleGroup(new String($groupName)); $setsMap->add($groupName, $group); } else { $group = $setsMap->get($groupName); } try { // add the user to the group $group->addMember($aslm->createIdentity(new String($name))); // log a message $application->getNamingDirectory()->search(NamingDirectoryKeys::SYSTEM_LOGGER)->debug(sprintf('Assign user to role: %s', $name)); } catch (\Exception $e) { $application->getNamingDirectory()->search(NamingDirectoryKeys::SYSTEM_LOGGER)->error(sprintf('Failed to create principal: %s', $name)); } // load one group after another } while ($row = $statement->fetch(\PDO::FETCH_OBJ)); } catch (NamingException $ne) { throw new LoginException($ne->__toString()); } catch (\PDOException $pdoe) { throw new LoginException($pdoe->__toString()); } // close the prepared statement if ($statement != null) { try { $statement->closeCursor(); } catch (\Exception $e) { $application->getNamingDirectory()->search(NamingDirectoryKeys::SYSTEM_LOGGER)->error($e->__toString()); } } // close the DBAL connection if ($connection != null) { try { $connection->close(); } catch (\Exception $e) { $application->getNamingDirectory()->search(NamingDirectoryKeys::SYSTEM_LOGGER)->error($e->__toString()); } } // return the prepared groups return $setsMap->toArray(); }
/** * Calls the HashMap method add. * * @param string $key Holds the key of the value to return * @param mixed $value Holds the value to add to the properties * @param string $section Holds a string with the section name to return the key for (only matters if sections is set to TRUE) * * @return void * @throws \AppserverIo\Lang\NullPointerException Is thrown if the passed key, or, if sections are TRUE, the passed section is NULL */ public function setProperty($key, $value, $section = null) { // check if the sections are included if ($this->sections) { // if the passed section OR the passed key is NULL throw an exception if ($section == null) { throw new NullPointerException('Passed section is null'); } if ($key == null) { throw new NullPointerException('Passed key is null'); } // if the section exists ... if ($this->exists($section)) { // get all entries of the section $entries = new HashMap($this->get($section)); $entries->add($key, $value); } } else { // if the passed key is NULL throw an exception if ($key == null) { throw new NullPointerException('Passed key is null'); } // add the value with the passed $this->add($key, $value); } }
/** * Initializes the manager instance. * * @param \AppserverIo\Psr\Application\ApplicationInterface $application The application instance * * @return void * @see \AppserverIo\Psr\Application\ManagerInterface::initialize() * * @throws \Exception */ public function initialize(ApplicationInterface $application) { // query whether or not the web application folder exists if (is_dir($this->getWebappPath()) === false) { return; } // initialize the map for the realms $realms = new HashMap(); // query whether or not we've manager configuration found /** @var \AppserverIo\Appserver\Core\Api\Node\ManagerNodeInterface $managerNode */ if ($managerNode = $this->getManagerConfiguration()) { // initialize the security domains found in the manager configuration /** @var \AppserverIo\Appserver\Core\Api\Node\SecurityDomainNodeInterface $securityDomainNode */ foreach ($this->getManagerConfiguration()->getSecurityDomains() as $securityDomainNode) { // create the realm instance $realm = new Realm($this, $securityDomainNode->getName()); $realm->injectConfiguration($securityDomainNode); // add the initialized security domain to the map $realms->add($realm->getName(), $realm); } } // inject the map with the realms $this->injectRealms($realms); // initialize the deployment descriptor parser and parse the web application's deployment descriptor for servlets $deploymentDescriptorParser = new DeploymentDescriptorParser(); $deploymentDescriptorParser->injectAuthenticationContext($this); $deploymentDescriptorParser->parse(); }
/** * If hashing is enabled, this method is called from login() prior to password validation. * * Subclasses may override it to provide customized password hashing, for example by adding * user-specific information or salting. * * The default version calculates the hash based on the following options: * * hashAlgorithm: The digest algorithm to use. * hashEncoding: The format used to store the hashes (base64 or hex) * hashCharset: The encoding used to convert the password to bytes * * for hashing. * * digestCallback: The class name of the digest callback implementation that includes * pre/post digest content like salts. * * It will return null if the hash fails for any reason, which will in turn * cause validatePassword() to fail. * * @param \AppserverIo\Lang\String $name Ignored in default version * @param \AppserverIo\Lang\String $password The password string to be hashed * * @return \AppserverIo\Lang\String The hashed password * @throws \AppserverIo\Appserver\ServletEngine\Security\SecurityException Is thrown if there is a failure to load the digestCallback */ protected function createPasswordHash(string $name, string $password) { // initialize the callback $callback = null; // query whether or not we've a callback configured if ($this->params->exists(ParamKeys::DIGEST_CALLBACK)) { try { // load the callback class name and create a new callback instance $callbackClassName = $this->params->get(ParamKeys::DIGEST_CALLBACK); $callback = new $callbackClassName(); // initialize the callback $tmp = new HashMap($this->params->toIndexedArray()); $tmp->add(SharedStateKeys::LOGIN_NAME, $name); $tmp->add(SharedStateKeys::LOGIN_PASSWORD, $password); $callback->init($tmp); } catch (\Exception $e) { throw new SecurityException("Failed to load DigestCallback"); } } // hash and return the password return Util::createPasswordHash($this->hashAlgorithm, $this->hashEncoding, $this->hashCharset, $name, $password, $callback); }