-
-
Save tabbi89/a7fa08b238cd02e3f2d3 to your computer and use it in GitHub Desktop.
Revisions
-
kbond revised this gist
Oct 1, 2015 . No changes.There are no files selected for viewing
-
kbond revised this gist
Oct 1, 2015 . No changes.There are no files selected for viewing
-
kbond revised this gist
Oct 1, 2015 . 2 changed files with 8 additions and 7 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -16,7 +16,8 @@ abstract class GuardAuthenticator extends AbstractGuardAuthenticator { /** * NOTE: I chose to throw an HTTP Exception here to let the response be rendered elsewhere - * separation of concerns and all... You could always return a JsonResponse here. */ public function onAuthenticationFailure(Request $request, AuthenticationException $exception) { @@ -26,8 +27,6 @@ public function onAuthenticationFailure(Request $request, AuthenticationExceptio $message = $exception->getMessageKey(); } throw new HttpException(401, $message); } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -8,12 +8,14 @@ class UserController extends Controller { /** * NOTE: I don't return a response in the UsernamePasswordGuardAuthenticator * because I wanted a controller to do the rendering. You could always * return a JsonResponse in UsernamePasswordGuardAuthenticator::onAuthenticationSuccess(). * If you do that, this class/method is no longer required. */ public function loginAction() { $token = $this->get('jwt_coder')->encode([ 'username' => $this->getUser()->getUsername() ]); -
kbond revised this gist
Oct 1, 2015 . 1 changed file with 3 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -10,9 +10,9 @@ class UserController extends Controller { public function loginAction() { // NOTE: I don't return a response in the UsernamePasswordGuardAuthenticator // because I wanted a controller to do the rendering. You could always // return a JsonResponse in UsernamePasswordGuardAuthenticator::onAuthenticationSuccess() $token = $this->get('jwt_coder')->encode([ 'username' => $this->getUser()->getUsername() -
kbond revised this gist
Oct 1, 2015 . 2 changed files with 6 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -26,6 +26,8 @@ public function onAuthenticationFailure(Request $request, AuthenticationExceptio $message = $exception->getMessageKey(); } // NOTE: I chose to throw an HTTP Exception here to let the response be rendered elsewhere - // separation of concerns and all... You could always return a JsonResponse here. throw new HttpException(401, $message); } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -10,6 +10,10 @@ class UserController extends Controller { public function loginAction() { // NOTE: I don't return a response in the UsernamePasswordGuardAuthenticator because I wanted a controller // to do the rendering. You could always return a JsonResponse in // UsernamePasswordGuardAuthenticator::onAuthenticationSuccess() $token = $this->get('jwt_coder')->encode([ 'username' => $this->getUser()->getUsername() ]); -
kbond created this gist
Oct 1, 2015 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,18 @@ <?php // app/AppKernel.php use Symfony\Component\Config\Loader\LoaderInterface; use Symfony\Component\HttpKernel\Kernel; class AppKernel extends Kernel { public function registerBundles() { return = [ new Symfony\Bundle\FrameworkBundle\FrameworkBundle(), new Symfony\Bundle\SecurityBundle\SecurityBundle(), new KnpU\GuardBundle\KnpUGuardBundle(), new AppBundle\AppBundle(), ]; } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,55 @@ <?php // src/AppBundle/Security/GuardAuthenticator.php namespace AppBundle\Security; use KnpU\Guard\AbstractGuardAuthenticator; use KnpU\Guard\Exception\CustomAuthenticationException; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Exception\AuthenticationException; /** * @author Kevin Bond <kevinbond@gmail.com> */ abstract class GuardAuthenticator extends AbstractGuardAuthenticator { /** * {@inheritdoc} */ public function onAuthenticationFailure(Request $request, AuthenticationException $exception) { $message = 'Invalid Credentials'; if ($exception instanceof CustomAuthenticationException) { $message = $exception->getMessageKey(); } throw new HttpException(401, $message); } /** * {@inheritdoc} */ public function start(Request $request, AuthenticationException $authException = null) { // noop } /** * {@inheritdoc} */ public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey) { // noop } /** * {@inheritdoc} */ public function supportsRememberMe() { return false; } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,8 @@ <?php // src/AppBundle/Exception/InvalidJWTException.php namespace AppBundle\Exception; class InvalidJWTException extends \UnexpectedValueException { } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,80 @@ <?php // src/AppBundle/Service/JWTCoder.php namespace AppBundle\Service; use Namshi\JOSE\JWS; use AppBundle\Exception\InvalidJWTException; /** * @author Kevin Bond <kevinbond@gmail.com> */ class JWTCoder { const ALG = 'HS256'; private $key; public function __construct($key) { $this->key = $key; } /** * @param array $payload * @param int $ttl * * @return string */ public function encode(array $payload, $ttl = 86400) { $payload['iat'] = time(); $payload['exp'] = time() + $ttl; $jws = new JWS([ 'typ' => 'JWS', 'alg' => self::ALG, ]); $jws->setPayload($payload); $jws->sign($this->key); return $jws->getTokenString(); } /** * @param string $token * * @return array * * @throws InvalidJWTException */ public function decode($token) { $jws = JWS::load($token); if (!$jws->verify($this->key, self::ALG)) { throw new InvalidJWTException('Invalid JWT'); } if ($this->isExpired($payload = $jws->getPayload())) { throw new InvalidJWTException('Expired JWT'); } return $payload; } /** * @param array $payload * * @return bool */ private function isExpired($payload) { if (isset($payload['exp']) && is_numeric($payload['exp'])) { return (time() - $payload['exp']) > 0; } return false; } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,70 @@ <?php // src/AppBundle/Security/JWTGuardAuthenticator.php namespace AppBundle\Security; use KnpU\Guard\Exception\CustomAuthenticationException; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserProviderInterface; use AppBundle\Exception\InvalidJWTException; use AppBundle\Service\JWTCoder; /** * @author Kevin Bond <kevinbond@gmail.com> */ final class JWTGuardAuthenticator extends GuardAuthenticator { private $jwtCoder; public function __construct(JWTCoder $jwtCoder) { $this->jwtCoder = $jwtCoder; } /** * {@inheritdoc} */ public function getCredentials(Request $request) { if (!$request->headers->has('Authorization')) { throw CustomAuthenticationException::createWithSafeMessage('Missing Authorization Header'); } $headerParts = explode(' ', $request->headers->get('Authorization')); if (!(count($headerParts) === 2 && $headerParts[0] === 'Bearer')) { throw CustomAuthenticationException::createWithSafeMessage('Malformed Authorization Header'); } return $headerParts[1]; } /** * {@inheritdoc} */ public function getUser($credentials, UserProviderInterface $userProvider) { try { $payload = $this->jwtCoder->decode($credentials); } catch (InvalidJWTException $e) { throw CustomAuthenticationException::createWithSafeMessage($e->getMessage()); } catch (\Exception $e) { throw CustomAuthenticationException::createWithSafeMessage('Malformed JWT'); } if (!isset($payload['username'])) { throw CustomAuthenticationException::createWithSafeMessage('Invalid JWT'); } return $userProvider->loadUserByUsername($payload['username']); } /** * {@inheritdoc} */ public function checkCredentials($credentials, UserInterface $user) { // noop } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,19 @@ <?php // src/AppBundle/Controller/UserController.php namespace AppBundle\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\JsonResponse; class UserController extends Controller { public function loginAction() { $token = $this->get('jwt_coder')->encode([ 'username' => $this->getUser()->getUsername() ]); return new JsonResponse(['token' => $token]); } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,59 @@ <?php // src/AppBundle/Security/UsernamePasswordGuardAuthenticator.php namespace AppBundle\Security; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException; use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface; use Symfony\Component\Security\Core\Exception\BadCredentialsException; use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserProviderInterface; /** * @author Kevin Bond <kevinbond@gmail.com> */ final class UsernamePasswordGuardAuthenticator extends GuardAuthenticator { private $passwordEncoder; public function __construct(UserPasswordEncoderInterface $passwordEncoder) { $this->passwordEncoder = $passwordEncoder; } /** * {@inheritdoc} */ public function getCredentials(Request $request) { if (!$request->isMethod('POST')) { throw new MethodNotAllowedHttpException(['POST']); } return [ 'username' => $request->request->get('username'), 'password' => $request->request->get('password'), ]; } /** * {@inheritdoc} */ public function getUser($credentials, UserProviderInterface $userProvider) { return $userProvider->loadUserByUsername($credentials['username']); } /** * {@inheritdoc} */ public function checkCredentials($credentials, UserInterface $user) { $plainPassword = $credentials['password']; if (!$this->passwordEncoder->isPasswordValid($user, $plainPassword)) { throw new BadCredentialsException(); } } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,7 @@ { "require": { "symfony/symfony": "~2.7.4", "namshi/jose": "~6.0", "knpuniversity/guard-bundle": "~0.3" } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,16 @@ # ... services: username_password_guard_authenticator: class: AppBundle\Security\UsernamePasswordGuardAuthenticator arguments: [@security.password_encoder] public: false jwt_guard_authenticator: class: AppBundle\Security\JWTGuardAuthenticator arguments: [@jwt_coder] public: false jwt_coder: class: AppBundle\Service\JWTCoder arguments: [%secret%] This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,3 @@ login: path: /login defaults: { _controller: AppBundle:User:login } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,24 @@ security: encoders: Symfony\Component\Security\Core\User\UserInterface: plaintext # change for real app providers: in_memory: # change for real app memory: users: user: { password: userpass } firewalls: login: pattern: ^/login$ stateless: true knpu_guard: authenticators: - username_password_guard_authenticator api: pattern: ^/api stateless: true knpu_guard: authenticators: - jwt_guard_authenticator