Skip to content

Commit

Permalink
Add an ip authenticator guard and an ip whitelist
Browse files Browse the repository at this point in the history
  • Loading branch information
Arakmar committed Apr 28, 2019
1 parent 303d8f5 commit 1fbd5ec
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 2 deletions.
4 changes: 4 additions & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,7 @@ OAUTH_TOKEN_URL=http://membres.yourcoop.local/oauth/v2/token
OAUTH_AUTH_URL=http://membres.yourcoop.local/oauth/v2/auth
OAUTH_INFOS_URL=http://membres.yourcoop.local/api/oauth/nextcloud_user
###< hwi/oauth-bundle ###

###> CUSTOM ###
APP_VIP_IPS=127.0.0.1
###< CUSTOM ###
4 changes: 4 additions & 0 deletions config/packages/security.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ security:
failure_path: /login
oauth_user_provider:
service: hwi_oauth.user.provider
guard:
authenticators:
- App\Security\IpAuthenticator

logout:
path: /logout
target: /
Expand Down
4 changes: 4 additions & 0 deletions config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@
# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
app.vip_ips: '%env(APP_VIP_IPS)%'

services:
# default configuration for services in *this* file
_defaults:
autowire: true # Automatically injects dependencies in your services.
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
bind:
$vipIps: '%app.vip_ips%'

# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
Expand All @@ -31,3 +34,4 @@ services:
arguments: ["@security.http_utils", {}]
tags:
- { name: 'monolog.logger', channel: 'security' }

5 changes: 3 additions & 2 deletions src/Controller/UserController.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ public function loginStatus()
$user = $this->getUser();

$response = [
'logged' => $user !== null,
'logged' => $this->isGranted('ROLE_USER'),
'vip_ip' => $this->isGranted('ROLE_VIP_IP'),
'user' => null,
'oauth_url' => $this->generateUrl('hwi_oauth_service_redirect', ['service' => 'custom'])
];
Expand All @@ -40,4 +41,4 @@ public function loginStatus()

return $this->json($response);
}
}
}
87 changes: 87 additions & 0 deletions src/Security/IpAuthenticator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<?php

namespace App\Security;

use HWI\Bundle\OAuthBundle\Security\Core\User\OAuthUser;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
use Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken;

class IpAuthenticator extends AbstractGuardAuthenticator
{
private $vipIps;

public function __construct(?string $vipIps)
{
$this->vipIps = $vipIps;
}

public function start(Request $request, AuthenticationException $authException = null)
{
$data = [
// you might translate this message
'message' => 'Authentication Required'
];

return new JsonResponse($data, Response::HTTP_UNAUTHORIZED);
}

public function supports(Request $request)
{
$ip = $request->getClientIp();

$vipIpArray = explode(',', $this->vipIps);
return (isset($ip) && in_array($ip, $vipIpArray));
}


public function getCredentials(Request $request)
{
return [
'ip' => $request->getClientIp()
];
}

public function getUser($credentials, UserProviderInterface $userProvider)
{
return new OAuthUser('anonymous');
}

public function checkCredentials($credentials, UserInterface $user)
{
return true;
}

public function onAuthenticationFailure(Request $request, AuthenticationException $exception)
{
return null;
}

public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
return null;
}

public function supportsRememberMe()
{
return false;
}

public function createAuthenticatedToken(UserInterface $user, $providerKey)
{
$roles = $user->getRoles();
$roles[] = 'ROLE_VIP_IP';

return new PostAuthenticationGuardToken(
$user,
$providerKey,
$roles
);
}
}

0 comments on commit 1fbd5ec

Please sign in to comment.