/**
  * Logs in a user.
  *
  * @param \Symfony\Component\HttpFoundation\Request $request
  *   The request.
  *
  * @return \Symfony\Component\HttpFoundation\Response
  *   A response which contains the ID and CSRF token.
  */
 public function login(Request $request)
 {
     $format = $this->getRequestFormat($request);
     $content = $request->getContent();
     $credentials = $this->serializer->decode($content, $format);
     if (!isset($credentials['name']) && !isset($credentials['pass'])) {
         throw new BadRequestHttpException('Missing credentials.');
     }
     if (!isset($credentials['name'])) {
         throw new BadRequestHttpException('Missing credentials.name.');
     }
     if (!isset($credentials['pass'])) {
         throw new BadRequestHttpException('Missing credentials.pass.');
     }
     $this->floodControl($request, $credentials['name']);
     if ($this->userIsBlocked($credentials['name'])) {
         throw new BadRequestHttpException('The user has not been activated or is blocked.');
     }
     if ($uid = $this->userAuth->authenticate($credentials['name'], $credentials['pass'])) {
         $this->flood->clear('user.http_login', $this->getLoginFloodIdentifier($request, $credentials['name']));
         /** @var \Drupal\user\UserInterface $user */
         $user = $this->userStorage->load($uid);
         $this->userLoginFinalize($user);
         // Send basic metadata about the logged in user.
         $response_data = [];
         if ($user->get('uid')->access('view', $user)) {
             $response_data['current_user']['uid'] = $user->id();
         }
         if ($user->get('roles')->access('view', $user)) {
             $response_data['current_user']['roles'] = $user->getRoles();
         }
         if ($user->get('name')->access('view', $user)) {
             $response_data['current_user']['name'] = $user->getAccountName();
         }
         $response_data['csrf_token'] = $this->csrfToken->get('rest');
         $logout_route = $this->routeProvider->getRouteByName('user.logout.http');
         // Trim '/' off path to match \Drupal\Core\Access\CsrfAccessCheck.
         $logout_path = ltrim($logout_route->getPath(), '/');
         $response_data['logout_token'] = $this->csrfToken->get($logout_path);
         $encoded_response_data = $this->serializer->encode($response_data, $format);
         return new Response($encoded_response_data);
     }
     $flood_config = $this->config('user.flood');
     if ($identifier = $this->getLoginFloodIdentifier($request, $credentials['name'])) {
         $this->flood->register('user.http_login', $flood_config->get('user_window'), $identifier);
     }
     // Always register an IP-based failed login event.
     $this->flood->register('user.failed_login_ip', $flood_config->get('ip_window'));
     throw new BadRequestHttpException('Sorry, unrecognized username or password.');
 }
Пример #2
0
 /**
  * {@inheritdoc}
  */
 public function authenticate(Request $request)
 {
     $flood_config = $this->configFactory->get('user.flood');
     $username = $request->headers->get('PHP_AUTH_USER');
     $password = $request->headers->get('PHP_AUTH_PW');
     // Flood protection: this is very similar to the user login form code.
     // @see \Drupal\user\Form\UserLoginForm::validateAuthentication()
     // Do not allow any login from the current user's IP if the limit has been
     // reached. Default is 50 failed attempts allowed in one hour. This is
     // independent of the per-user limit to catch attempts from one IP to log
     // in to many different user accounts.  We have a reasonably high limit
     // since there may be only one apparent IP for all users at an institution.
     if ($this->flood->isAllowed('basic_auth.failed_login_ip', $flood_config->get('ip_limit'), $flood_config->get('ip_window'))) {
         $accounts = $this->entityManager->getStorage('user')->loadByProperties(array('name' => $username, 'status' => 1));
         $account = reset($accounts);
         if ($account) {
             if ($flood_config->get('uid_only')) {
                 // Register flood events based on the uid only, so they apply for any
                 // IP address. This is the most secure option.
                 $identifier = $account->id();
             } else {
                 // The default identifier is a combination of uid and IP address. This
                 // is less secure but more resistant to denial-of-service attacks that
                 // could lock out all users with public user names.
                 $identifier = $account->id() . '-' . $request->getClientIP();
             }
             // Don't allow login if the limit for this user has been reached.
             // Default is to allow 5 failed attempts every 6 hours.
             if ($this->flood->isAllowed('basic_auth.failed_login_user', $flood_config->get('user_limit'), $flood_config->get('user_window'), $identifier)) {
                 $uid = $this->userAuth->authenticate($username, $password);
                 if ($uid) {
                     $this->flood->clear('basic_auth.failed_login_user', $identifier);
                     return $this->entityManager->getStorage('user')->load($uid);
                 } else {
                     // Register a per-user failed login event.
                     $this->flood->register('basic_auth.failed_login_user', $flood_config->get('user_window'), $identifier);
                 }
             }
         }
     }
     // Always register an IP-based failed login event.
     $this->flood->register('basic_auth.failed_login_ip', $flood_config->get('ip_window'));
     return [];
 }
 /**
  * Checks supplied username/password against local users table.
  *
  * If successful, $form_state->get('uid') is set to the matching user ID.
  */
 public function validateAuthentication(array &$form, FormStateInterface $form_state)
 {
     $password = trim($form_state->getValue('pass'));
     $flood_config = $this->config('user.flood');
     if (!$form_state->isValueEmpty('name') && !empty($password)) {
         // Do not allow any login from the current user's IP if the limit has been
         // reached. Default is 50 failed attempts allowed in one hour. This is
         // independent of the per-user limit to catch attempts from one IP to log
         // in to many different user accounts.  We have a reasonably high limit
         // since there may be only one apparent IP for all users at an institution.
         if (!$this->flood->isAllowed('user.failed_login_ip', $flood_config->get('ip_limit'), $flood_config->get('ip_window'))) {
             $form_state->set('flood_control_triggered', 'ip');
             return;
         }
         $accounts = $this->userStorage->loadByProperties(array('name' => $form_state->getValue('name'), 'status' => 1));
         $account = reset($accounts);
         if ($account) {
             if ($flood_config->get('uid_only')) {
                 // Register flood events based on the uid only, so they apply for any
                 // IP address. This is the most secure option.
                 $identifier = $account->id();
             } else {
                 // The default identifier is a combination of uid and IP address. This
                 // is less secure but more resistant to denial-of-service attacks that
                 // could lock out all users with public user names.
                 $identifier = $account->id() . '-' . $this->getRequest()->getClientIP();
             }
             $form_state->set('flood_control_user_identifier', $identifier);
             // Don't allow login if the limit for this user has been reached.
             // Default is to allow 5 failed attempts every 6 hours.
             if (!$this->flood->isAllowed('user.failed_login_user', $flood_config->get('user_limit'), $flood_config->get('user_window'), $identifier)) {
                 $form_state->set('flood_control_triggered', 'user');
                 return;
             }
         }
         // We are not limited by flood control, so try to authenticate.
         // Store $uid in form state as a flag for self::validateFinal().
         $uid = $this->userAuth->authenticate($form_state->getValue('name'), $password);
         $form_state->set('uid', $uid);
     }
 }
Пример #4
0
 /**
  * Mostly copied from the basic_auth module
  *
  * @param $loginInfo
  * @param null $extra
  * @return array|\Drupal\Core\Entity\EntityInterface|null
  */
 public function processAuthenticate($loginInfo, $extra = null)
 {
     if (is_string($loginInfo) && $loginInfo == strtolower("anonymous")) {
         return $this->processAnonymous();
     }
     if (is_string($loginInfo)) {
         return $this->processToken($loginInfo);
     }
     if (isset($loginInfo['user']) && isset($loginInfo['pass'])) {
         $username = $loginInfo['user'];
         $password = $loginInfo['pass'];
     } else {
         return array("FAILURE");
     }
     //        $flood_config = $this->configFactory->get('user.flood');
     //
     //        // Flood protection: this is very similar to the user login form code.
     //        // @see \Drupal\user\Form\UserLoginForm::validateAuthentication()
     //        // Do not allow any login from the current user's IP if the limit has been
     //        // reached. Default is 50 failed attempts allowed in one hour. This is
     //        // independent of the per-user limit to catch attempts from one IP to log
     //        // in to many different user accounts.  We have a reasonably high limit
     //        // since there may be only one apparent IP for all users at an institution.
     //        if ($this->flood->isAllowed(
     //            'thruway_auth.failed_login_ip',
     //            $flood_config->get('ip_limit'),
     //            $flood_config->get('ip_window')
     //        )
     //        ) {
     $accounts = $this->entityManager->getStorage('user')->loadByProperties(array('name' => $username, 'status' => 1));
     $account = reset($accounts);
     if ($account) {
         //                if ($flood_config->get('uid_only')) {
         //                    // Register flood events based on the uid only, so they apply for any
         //                    // IP address. This is the most secure option.
         //                    $identifier = $account->id();
         //                } else {
         //                    // The default identifier is a combination of uid and Session IP address. This
         //                    // is less secure but more resistant to denial-of-service attacks that
         //                    // could lock out all users with public user names.
         //                    $identifier = $account->id() . '-' . $this->getSession()->getSessionId();
         //                }
         //                // Don't allow login if the limit for this user has been reached.
         //                // Default is to allow 5 failed attempts every 6 hours.
         //                if ($this->flood->isAllowed(
         //                    'thruway_auth.failed_login_user',
         //                    $flood_config->get('user_limit'),
         //                    $flood_config->get('user_window'),
         //                    $identifier
         //                )
         //                ) {
         $uid = $this->userAuth->authenticate($username, $password);
         if ($uid) {
             //                        $this->flood->clear('thruway_auth.failed_login_user', $identifier);
             return ["SUCCESS", ["authid" => $this->entityManager->getStorage('user')->load($uid)->getEmail()]];
         }
         //                    else {
         //                        // Register a per-user failed login event.
         //                        $this->flood->register(
         //                            'thruway_auth.failed_login_user',
         //                            $flood_config->get('user_window'),
         //                            $identifier
         //                        );
         //                    }
         //                }
         //            }
     }
     // Always register an IP-based failed login event.
     //        $this->flood->register('basic_auth.failed_login_ip', $flood_config->get('ip_window'));
     return array("FAILURE");
 }