<?php namespace DG\JiraAuthBundle\Security\Authentication\Token; use Symfony\Component\Security\Core\Authentication\Token\AbstractToken; class JiraToken extends AbstractToken { protected $jira_login; protected $jira_password; public function __construct(array $roles = array('ROLE_USER')){ parent::__construct($roles); $this->setAuthenticated(count($roles) > 0); } public function getJiraLogin(){ return $this->jira_login; } public function setJiraLogin($jira_login){ $this->jira_login = $jira_login; } public function getJiraPassword(){ return $this->jira_password; } public function setJiraPassword($jira_password){ $this->jira_password = $jira_password; } public function serialize() { return serialize(array($this->jira_login, $this->jira_password, parent::serialize())); } public function unserialize($serialized) { list($this->jira_login, $this->jira_password, $parent_data) = unserialize($serialized); parent::unserialize($parent_data); } public function getCredentials(){ return ''; } }
<?php namespace DG\JiraAuthBundle\Security\Firewall; use DG\JiraAuthBundle\Security\Authentication\Token\JiraToken; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Psr\Log\LoggerInterface; use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Exception\AuthenticationException; use Symfony\Component\Security\Core\SecurityContextInterface; use Symfony\Component\Security\Http\Firewall\AbstractAuthenticationListener; class JiraListener extends AbstractAuthenticationListener { protected function attemptAuthentication(Request $request){ if ($this->options['post_only'] && 'post' !== strtolower($request->getMethod())) { if (null !== $this->logger) { $this->logger->debug(sprintf('Authentication method not supported: %s.', $request->getMethod())); } return null; } $username = trim($request->get($this->options['username_parameter'], null, true)); $password = $request->get($this->options['password_parameter'], null, true); $request->getSession()->set(SecurityContextInterface::LAST_USERNAME, $username); $request->getSession()->set('jira_auth', base64_encode($username.':'.$password)); $token = new JiraToken(); $token->setJiraLogin($username); $token->setJiraPassword($password); return $this->authenticationManager->authenticate($token); } }
<?php namespace DG\JiraAuthBundle\Jira; use Buzz\Message; use Buzz\Client\Curl; class JiraRest { private $jiraUrl = ''; public function __construct($jiraUrl){ $this->jiraUrl = $jiraUrl; } public function getUserInfo($username, $password){ $request = new Message\Request( 'GET', '/rest/api/2/user?username=' . $username, $this->jiraUrl ); $request->addHeader('Authorization: Basic ' . base64_encode($username . ':' . $password) ); $request->addHeader('Content-Type: application/json'); $response = new Message\Response(); $client = new Curl(); $client->setTimeout(10); $client->send($request, $response); return $response; } }
<?php namespace DG\JiraAuthBundle\Security\Authentication\Provider; use DG\JiraAuthBundle\Entity\User; use DG\JiraAuthBundle\Jira\JiraRest; use DG\JiraAuthBundle\Security\Authentication\Token\JiraToken; use Symfony\Component\Security\Core\Authentication\Provider\AuthenticationProviderInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Exception\AuthenticationException; use Symfony\Component\Security\Core\User\UserProviderInterface; class JiraProvider implements AuthenticationProviderInterface { private $userProvider; private $jiraRest; public function __construct(UserProviderInterface $userProvider, $providerKey, JiraRest $jiraRest) { $this->userProvider = $userProvider; $this->jiraRest = $jiraRest; } public function supports(TokenInterface $token) { return $token instanceof JiraToken; } public function authenticate(TokenInterface $token) { $user = $this->checkUserAuthentication($token); $token->setUser($user); return $token; } public function checkUserAuthentication(JiraToken $token){ $response = $this->jiraRest->getUserInfo($token->getJiraLogin(), $token->getJiraPassword()); if(!in_array('HTTP/1.1 200 OK', $response->getHeaders())){ throw new AuthenticationException( 'Incorrect email and/or password' ); } $userInfo = json_decode($response->getContent()); $user = new User(); $user->setUsername($userInfo->name); $user->setBase64Hash(base64_encode($token->getJiraLogin() . ':' . $token->getJiraPassword())); $user->setEmail($userInfo->emailAddress); $user->addRole('ROLE_USER'); return $user; } }
<?php namespace DG\JiraAuthBundle\User; use DG\JiraAuthBundle\Entity\User; use DG\JiraAuthBundle\Jira\JiraRest; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Component\Security\Core\Exception\UnsupportedUserException; use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserProviderInterface; use Symfony\Component\Security\Core\SecurityContextInterface; class JiraUserProvider implements UserProviderInterface { private $jiraRest; public function __construct(JiraRest $jiraRest){ $this->jiraRest = $jiraRest; } public function loadUserByUsername($username) { } public function refreshUser(UserInterface $user) { if (!$user instanceof User) { throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_class($user))); } $decodedUserData = base64_decode($user->getBase64Hash()); list($username, $password) = explode(':', $decodedUserData); $userInfoResponse = $this->jiraRest->getUserInfo($username, $password); $userInfo = json_decode($userInfoResponse->getContent()); $user = new User(); $user->setUsername($user->getUsername()); $user->setEmail($userInfo->emailAddress); $user->setBase64Hash($user->getBase64Hash()); $user->addRole('ROLE_USER'); return $user; } public function supportsClass($class) { return $class === 'DG\JiraAuthBundle\Entity\User'; } }
parameters: dg_jira_auth.user_provider.class: DG\JiraAuthBundle\User\JiraUserProvider dg_jira_auth.listener.class: DG\JiraAuthBundle\Security\Firewall\JiraListener dg_jira_auth.provider.class: DG\JiraAuthBundle\Security\Authentication\Provider\JiraProvider dg_jira_auth.handler.class: DG\JiraAuthBundle\Security\Authentication\Handler\JiraAuthenticationHandler dg_jira.rest.class: DG\JiraAuthBundle\Jira\JiraRest services: dg_jira.rest: class: %dg_jira.rest.class% arguments: - '%jira_url%' dg_jira_auth.user_provider: class: %dg_jira_auth.user_provider.class% arguments: - @dg_jira.rest dg_jira_auth.authentication_success_handler: class: %dg_jira_auth.handler.class% dg_jira_auth.authentication_failure_handler: class: %dg_jira_auth.handler.class% dg_jira_auth.authentication_provider: class: %dg_jira_auth.provider.class% arguments: [@dg_jira_auth.user_provider, '', @dg_jira.rest] dg_jira_auth.authentication_listener: class: %dg_jira_auth.listener.class% arguments: - @security.context - @security.authentication.manager - @security.authentication.session_strategy - @security.http_utils - '' - @dg_jira_auth.authentication_success_handler - @dg_jira_auth.authentication_failure_handler - '' - @logger - @event_dispatcher
<?php namespace DG\JiraAuthBundle\DependencyInjection\Security\Factory; use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\AbstractFactory; use Symfony\Component\Config\Definition\Builder\NodeDefinition; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\DefinitionDecorator; use Symfony\Component\DependencyInjection\Reference; class JiraFactory extends AbstractFactory { public function __construct(){ $this->addOption('username_parameter', '_username'); $this->addOption('password_parameter', '_password'); $this->addOption('intention', 'authenticate'); $this->addOption('post_only', true); } protected function createAuthProvider(ContainerBuilder $container, $id, $config, $userProviderId) { $provider = 'dg_jira_auth.authentication_provider.'.$id; $container ->setDefinition($provider, new DefinitionDecorator('dg_jira_auth.authentication_provider')) ->replaceArgument(1, $id) ; return $provider; } protected function getListenerId() { return 'dg_jira_auth.authentication_listener'; } public function getPosition() { return 'form'; } public function getKey() { return 'jira-form'; } protected function createListener($container, $id, $config, $userProvider) { $listenerId = parent::createListener($container, $id, $config, $userProvider); if (isset($config['csrf_provider'])) { $container ->getDefinition($listenerId) ->addArgument(new Reference($config['csrf_provider'])) ; } return $listenerId; } protected function createEntryPoint($container, $id, $config, $defaultEntryPoint) { $entryPointId = 'security.authentication.form_entry_point.'.$id; $container ->setDefinition($entryPointId, new DefinitionDecorator('security.authentication.form_entry_point')) ->addArgument(new Reference('security.http_utils')) ->addArgument($config['login_path']) ->addArgument($config['use_forward']) ; return $entryPointId; } }
$extension->addSecurityListenerFactory(new JiraFactory());
jira_auth_provider: id: dg_jira_auth.user_provider
jira_secured: provider: jira_auth_provider switch_user: false context: user pattern: /jira/.* jira_form: check_path: dg_jira_auth_check_path login_path: dg_jira_auth_login_path default_target_path: dg_jira_auth_private logout: path: dg_jira_auth_logout target: dg_jira_auth_public anonymous: true
- { path: ^/jira/public, role: IS_AUTHENTICATED_ANONYMOUSLY } - { path: ^/jira/private/login$, role: IS_AUTHENTICATED_ANONYMOUSLY } - { path: ^/jira/private(.*)$, role: ROLE_USER }
_jira_auth: resource: "@DGJiraAuthBundle/Resources/config/routing.yml" prefix: /jira/
Source: https://habr.com/ru/post/206888/
All Articles