wip: adds config options for oidc
This commit is contained in:
5
.env
5
.env
@@ -43,8 +43,11 @@ REDIS_HOST=redis://redis
|
|||||||
MAILER_DSN=null://null
|
MAILER_DSN=null://null
|
||||||
###< symfony/mailer ###
|
###< symfony/mailer ###
|
||||||
|
|
||||||
|
AUTH_METHOD=form_login
|
||||||
|
|
||||||
###> drenso/symfony-oidc-bundle ###
|
###> drenso/symfony-oidc-bundle ###
|
||||||
OIDC_WELL_KNOWN_URL="Enter the .well-known url for the OIDC provider"
|
OIDC_WELL_KNOWN_URL="https://oidc/.well-known"
|
||||||
OIDC_CLIENT_ID="Enter your OIDC client id"
|
OIDC_CLIENT_ID="Enter your OIDC client id"
|
||||||
OIDC_CLIENT_SECRET="Enter your OIDC client secret"
|
OIDC_CLIENT_SECRET="Enter your OIDC client secret"
|
||||||
|
OIDC_BYPASS_FORM_LOGIN=false
|
||||||
###< drenso/symfony-oidc-bundle ###
|
###< drenso/symfony-oidc-bundle ###
|
||||||
|
|||||||
@@ -24,9 +24,14 @@ security:
|
|||||||
logout:
|
logout:
|
||||||
path: /logout
|
path: /logout
|
||||||
provider: app_oidc
|
provider: app_oidc
|
||||||
|
form_login:
|
||||||
|
login_path: app_login
|
||||||
|
check_path: app_login
|
||||||
|
enable_csrf: true
|
||||||
oidc:
|
oidc:
|
||||||
login_path: '/login/oidc'
|
login_path: '/login/oidc'
|
||||||
check_path: '/login/oidc/auth'
|
check_path: '/login/oidc/auth'
|
||||||
|
entry_point: form_login
|
||||||
|
|
||||||
# activate different ways to authenticate
|
# activate different ways to authenticate
|
||||||
# https://symfony.com/doc/current/security.html#the-firewall
|
# https://symfony.com/doc/current/security.html#the-firewall
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
parameters:
|
parameters:
|
||||||
# App
|
# App
|
||||||
app.url: '%env(APP_URL)%'
|
app.url: '%env(APP_URL)%'
|
||||||
|
app.version: '%env(default:app.default.version:APP_VERSION)%'
|
||||||
|
|
||||||
# Debrid Services
|
# Debrid Services
|
||||||
app.debrid.real_debrid.key: '%env(REAL_DEBRID_KEY)%'
|
app.debrid.real_debrid.key: '%env(REAL_DEBRID_KEY)%'
|
||||||
@@ -34,7 +35,14 @@ parameters:
|
|||||||
app.default.version: '0.dev'
|
app.default.version: '0.dev'
|
||||||
app.default.timezone: 'America/Chicago'
|
app.default.timezone: 'America/Chicago'
|
||||||
|
|
||||||
app.version: '%env(default:app.default.version:APP_VERSION)%'
|
# Auth
|
||||||
|
auth.default.method: 'form_login'
|
||||||
|
auth.method: '%env(default:auth.default.method:AUTH_METHOD)%'
|
||||||
|
|
||||||
|
auth.oidc.well_known_url: '%env(OIDC_WELL_KNOWN_URL)%'
|
||||||
|
auth.oidc.client_id: '%env(OIDC_CLIENT_ID)%'
|
||||||
|
auth.oidc.client_secret: '%env(OIDC_CLIENT_SECRET)%'
|
||||||
|
auth.oidc.bypass_form_login: '%env(bool:OIDC_BYPASS_FORM_LOGIN)%'
|
||||||
|
|
||||||
services:
|
services:
|
||||||
# default configuration for services in *this* file
|
# default configuration for services in *this* file
|
||||||
|
|||||||
@@ -23,6 +23,21 @@ final class ConfigResolver
|
|||||||
|
|
||||||
#[Autowire(param: 'media.tvshows.path')]
|
#[Autowire(param: 'media.tvshows.path')]
|
||||||
private readonly ?string $tvshowsPath = null,
|
private readonly ?string $tvshowsPath = null,
|
||||||
|
|
||||||
|
#[Autowire(param: 'auth.method')]
|
||||||
|
private readonly ?string $authMethod = null,
|
||||||
|
|
||||||
|
#[Autowire(param: 'auth.oidc.well_known_url')]
|
||||||
|
private readonly ?string $authOidcWellKnownUrl = null,
|
||||||
|
|
||||||
|
#[Autowire(param: 'auth.oidc.client_id')]
|
||||||
|
private readonly ?string $authOidcClientId = null,
|
||||||
|
|
||||||
|
#[Autowire(param: 'auth.oidc.client_secret')]
|
||||||
|
private readonly ?string $authOidcClientSecret = null,
|
||||||
|
|
||||||
|
#[Autowire(param: 'auth.oidc.bypass_form_login')]
|
||||||
|
private ?bool $authOidcBypassFormLogin = null,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
public function validate(): bool
|
public function validate(): bool
|
||||||
@@ -46,4 +61,35 @@ final class ConfigResolver
|
|||||||
{
|
{
|
||||||
return $this->messages;
|
return $this->messages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function authIs(string $method): bool
|
||||||
|
{
|
||||||
|
if (strtolower($method) === strtolower($this->getAuthMethod())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAuthMethod(): string
|
||||||
|
{
|
||||||
|
return strtolower($this->authMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function bypassFormLogin(): bool
|
||||||
|
{
|
||||||
|
return $this->authOidcBypassFormLogin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAuthConfig(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'method' => $this->authMethod,
|
||||||
|
'oidc' => [
|
||||||
|
'well_known_url' => $this->authOidcWellKnownUrl,
|
||||||
|
'client_id' => $this->authOidcClientId,
|
||||||
|
'client_secret' => $this->authOidcClientSecret,
|
||||||
|
'bypass_form_login' => $this->authOidcBypassFormLogin,
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,29 +2,30 @@
|
|||||||
|
|
||||||
namespace App\User\Framework\Controller\Web;
|
namespace App\User\Framework\Controller\Web;
|
||||||
|
|
||||||
|
use App\Base\ConfigResolver;
|
||||||
use App\User\Framework\Repository\UserRepository;
|
use App\User\Framework\Repository\UserRepository;
|
||||||
use App\User\Framework\Security\OidcUserProvider;
|
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
use Drenso\OidcBundle\Exception\OidcException;
|
|
||||||
use Drenso\OidcBundle\OidcClientInterface;
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Bundle\SecurityBundle\Security;
|
use Symfony\Bundle\SecurityBundle\Security;
|
||||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\Routing\Attribute\Route;
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
use Symfony\Component\Security\Http\Attribute\IsGranted;
|
|
||||||
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
|
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
|
||||||
|
|
||||||
class LoginController extends AbstractController
|
class LoginController extends AbstractController
|
||||||
{
|
{
|
||||||
#[Route(path: '/login', name: 'app_login')]
|
#[Route(path: '/login', name: 'app_login')]
|
||||||
public function login(AuthenticationUtils $authenticationUtils, UserRepository $userRepository): Response
|
public function login(ConfigResolver $config, AuthenticationUtils $authenticationUtils, UserRepository $userRepository): Response
|
||||||
{
|
{
|
||||||
if ((new ArrayCollection($userRepository->findAll()))->count() === 0) {
|
if ((new ArrayCollection($userRepository->findAll()))->count() === 0) {
|
||||||
return $this->redirectToRoute('app_getting_started');
|
return $this->redirectToRoute('app_getting_started');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($config->authIs('oidc') && $config->bypassFormLogin()) {
|
||||||
|
return $this->redirectToRoute('app_login_oidc');
|
||||||
|
}
|
||||||
|
|
||||||
// get the login error if there is one
|
// get the login error if there is one
|
||||||
$error = $authenticationUtils->getLastAuthenticationError();
|
$error = $authenticationUtils->getLastAuthenticationError();
|
||||||
|
|
||||||
@@ -32,6 +33,7 @@ class LoginController extends AbstractController
|
|||||||
$lastUsername = $authenticationUtils->getLastUsername();
|
$lastUsername = $authenticationUtils->getLastUsername();
|
||||||
|
|
||||||
return $this->render('user/login.html.twig', [
|
return $this->render('user/login.html.twig', [
|
||||||
|
'show_oidc_button' => $config->authIs('oidc'),
|
||||||
'last_username' => $lastUsername,
|
'last_username' => $lastUsername,
|
||||||
'error' => $error,
|
'error' => $error,
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\User\Framework\Controller\Web;
|
namespace App\User\Framework\Controller\Web;
|
||||||
|
|
||||||
|
use App\Base\ConfigResolver;
|
||||||
use Drenso\OidcBundle\OidcClientInterface;
|
use Drenso\OidcBundle\OidcClientInterface;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Bundle\SecurityBundle\Security;
|
use Symfony\Bundle\SecurityBundle\Security;
|
||||||
@@ -11,9 +12,18 @@ use Symfony\Component\Routing\Attribute\Route;
|
|||||||
|
|
||||||
class LoginOidcController extends AbstractController
|
class LoginOidcController extends AbstractController
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
private ConfigResolver $configResolver,
|
||||||
|
) {}
|
||||||
|
|
||||||
#[Route('/login/oidc', name: 'app_login_oidc')]
|
#[Route('/login/oidc', name: 'app_login_oidc')]
|
||||||
public function oidcStart(OidcClientInterface $oidcClient): RedirectResponse
|
public function oidcStart(OidcClientInterface $oidcClient): RedirectResponse
|
||||||
{
|
{
|
||||||
|
if (false === $this->configResolver->authIs('oidc')) {
|
||||||
|
throw new \Exception('You must configure the OIDC environment variables before logging in at this route.');
|
||||||
|
}
|
||||||
|
|
||||||
// Redirect to authorization @ OIDC provider
|
// Redirect to authorization @ OIDC provider
|
||||||
return $oidcClient->generateAuthorizationRedirect();
|
return $oidcClient->generateAuthorizationRedirect();
|
||||||
}
|
}
|
||||||
@@ -21,6 +31,10 @@ class LoginOidcController extends AbstractController
|
|||||||
#[Route('/login/oidc/auth', name: 'app_login_oidc_auth')]
|
#[Route('/login/oidc/auth', name: 'app_login_oidc_auth')]
|
||||||
public function oidcAuthenticate(): RedirectResponse
|
public function oidcAuthenticate(): RedirectResponse
|
||||||
{
|
{
|
||||||
|
if (false === $this->configResolver->authIs('oidc')) {
|
||||||
|
throw new \Exception('You must configure the OIDC environment variables before logging in at this route.');
|
||||||
|
}
|
||||||
|
|
||||||
throw new \LogicException('This method can be blank - it will be intercepted by the "oidc" key on your firewall.');
|
throw new \LogicException('This method can be blank - it will be intercepted by the "oidc" key on your firewall.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,10 +52,16 @@
|
|||||||
<button type="submit" class="bg-green-600/40 px-1.5 py-1 w-full rounded-md text-gray-50 backdrop-filter backdrop-blur-sm border-2 border-green-500 hover:bg-green-700/40">
|
<button type="submit" class="bg-green-600/40 px-1.5 py-1 w-full rounded-md text-gray-50 backdrop-filter backdrop-blur-sm border-2 border-green-500 hover:bg-green-700/40">
|
||||||
Sign in
|
Sign in
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div class="flex">
|
|
||||||
<a href="{{ path('app_forgot_password_request') }}">Forgot password?</a>
|
|
||||||
</div>
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
{% if show_oidc_button == "oidc" %}
|
||||||
|
<a href="{{ path('app_login_oidc') }}" class="bg-sky-950/60 px-1.5 py-1 w-full rounded-md text-gray-50 text-center backdrop-filter backdrop-blur-sm border-2 border-gray-950 hover:bg-orange-700/40">
|
||||||
|
Sign in with OIDC
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div class="flex">
|
||||||
|
<a href="{{ path('app_forgot_password_request') }}">Forgot password?</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
Reference in New Issue
Block a user