Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
43399b443e | ||
|
|
727ade1a19 | ||
| 88ec7d7bb1 | |||
|
|
8c8ceb1279 | ||
|
|
f11d97ced0 | ||
| fc2d81b9ad | |||
|
|
87909a1c15 | ||
|
|
f254ab52ac | ||
|
|
570008ab6e | ||
|
|
1f88ce8cb0 | ||
|
|
f2e6a6b4cb | ||
|
|
eec425222b | ||
|
|
30bcc70c4f | ||
|
|
e719e3c6ff | ||
|
|
20015218a0 | ||
|
|
23de5882b0 | ||
|
|
56fba70416 | ||
|
|
f3d64ef323 | ||
|
|
ea95d68fb0 | ||
|
|
d1494427f2 | ||
|
|
c05aae70da |
@@ -5,11 +5,15 @@ namespace ABEL\Bundle\keycloakBearerOnlyAdapterBundle;
|
|||||||
|
|
||||||
|
|
||||||
use ABEL\Bundle\keycloakBearerOnlyAdapterBundle\DependencyInjection\ABELkeycloakBearerOnlyAdapterExtension;
|
use ABEL\Bundle\keycloakBearerOnlyAdapterBundle\DependencyInjection\ABELkeycloakBearerOnlyAdapterExtension;
|
||||||
|
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
|
||||||
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
use Symfony\Component\HttpKernel\Bundle\Bundle;
|
||||||
|
|
||||||
class ABELkeycloakBearerOnlyAdapterBundle extends Bundle
|
class ABELkeycloakBearerOnlyAdapterBundle extends Bundle
|
||||||
{
|
{
|
||||||
public function getContainerExtension()
|
/**
|
||||||
|
* @return ExtensionInterface|null
|
||||||
|
*/
|
||||||
|
public function getContainerExtension(): ?ExtensionInterface
|
||||||
{
|
{
|
||||||
if (null === $this->extension) {
|
if (null === $this->extension) {
|
||||||
$this->extension = new ABELkeycloakBearerOnlyAdapterExtension();
|
$this->extension = new ABELkeycloakBearerOnlyAdapterExtension();
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class ABELkeycloakBearerOnlyAdapterExtension extends Extension
|
|||||||
$definition->replaceArgument(4, $config['ssl_verification']);
|
$definition->replaceArgument(4, $config['ssl_verification']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getAlias()
|
public function getAlias(): string
|
||||||
{
|
{
|
||||||
return 'abel_keycloak_bearer_only_adapter';
|
return 'abel_keycloak_bearer_only_adapter';
|
||||||
}
|
}
|
||||||
|
|||||||
33
README.md
33
README.md
@@ -5,10 +5,15 @@ This Symfony bundle is an adapter that allows securing API using keycloak Bearer
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
> Befor installing the bundle, automatic packages configuration can be activated with the following command:
|
||||||
|
> ```
|
||||||
|
> composer config extra.symfony.allow-contrib true
|
||||||
|
> ```
|
||||||
|
|
||||||
With composer:
|
With composer:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ composer require abel/keycloak-bearer-only-adapter-bundle
|
composer require abel/keycloak-bearer-only-adapter-bundle
|
||||||
```
|
```
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
@@ -17,6 +22,15 @@ If you want to set up keycloak locally you can download it [here](https://www.ke
|
|||||||
|
|
||||||
### Bundle configuration
|
### Bundle configuration
|
||||||
|
|
||||||
|
#### Via a recipe (Automatic)
|
||||||
|
This bundle hase a Symfony recipe that allow the automation of configuration via the Symfony Flex Composer plugin.
|
||||||
|
To enable recipe for your project, run the following command:
|
||||||
|
|
||||||
|
```
|
||||||
|
composer config extra.symfony.allow-contrib true
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Manual
|
||||||
Having a running keycloak locally or in Docker and already configured a client with **Access Type = bearer-only**
|
Having a running keycloak locally or in Docker and already configured a client with **Access Type = bearer-only**
|
||||||
here is the configuration to use:
|
here is the configuration to use:
|
||||||
|
|
||||||
@@ -35,20 +49,25 @@ The best practice is to load your configuration from **.env** file.
|
|||||||
# .env
|
# .env
|
||||||
...
|
...
|
||||||
###> Abel_keycloak_bearer_only_adapter ###
|
###> Abel_keycloak_bearer_only_adapter ###
|
||||||
OAUTH_KEYCLOAK_ISSUER=http://keycloak.local:8080
|
OAUTH_KEYCLOAK_ISSUER=keycloak:8080
|
||||||
OAUTH_KEYCLOAK_REALM=my_realm
|
OAUTH_KEYCLOAK_REALM=my_realm
|
||||||
OAUTH_KEYCLOAK_CLIENT_ID=my_bearer_client
|
OAUTH_KEYCLOAK_CLIENT_ID=my_bearer_client
|
||||||
OAUTH_KEYCLOAK_CLIENT_SECRET=my_bearer_client_secret
|
OAUTH_KEYCLOAK_CLIENT_SECRET=my_bearer_client_secret
|
||||||
###< Abel_keycloak_bearer_only_adapter ###
|
###< Abel_keycloak_bearer_only_adapter ###
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
> Since Keycloak 17 the default distribution is now powered by **Quarkus**, while the legacy **WildFly** powered distribution will still be around until June 2022 <br>
|
||||||
|
> The new distribution introduces a number of breaking changes, including: <br>
|
||||||
|
> - `/auth` removed from the default context path <br>
|
||||||
|
> ⚠️ **If you are using a legacy version make sure to include /auth in OAUTH_KEYCLOAK_ISSUER** <br>
|
||||||
|
> Example: `keycloak:8080/auth`
|
||||||
|
|
||||||
In case of using Keycloak with Docker locally replace **issuer** value with your keycloak container reference in the network
|
In case of using Keycloak with Docker locally replace **issuer** value with your keycloak container reference in the network
|
||||||
|
|
||||||
For example, you can use the container IPAdresse, that you can get using this command:
|
For example, you can use the service name, or container IPAdresse that you can get using this command:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ docker inspect <container id> | grep "IPAddress"
|
docker inspect <container id> | grep "IPAddress"
|
||||||
```
|
```
|
||||||
### Symfony security configuration
|
### Symfony security configuration
|
||||||
|
|
||||||
@@ -76,6 +95,7 @@ security:
|
|||||||
access_control:
|
access_control:
|
||||||
- { path: ^/api/, roles: ROLE_API }
|
- { path: ^/api/, roles: ROLE_API }
|
||||||
```
|
```
|
||||||
|
> :information_source: Referring to Symfony [documentation](https://symfony.com/doc/5.3/security.html#roles), roles must start with **ROLE_** (otherwise, things won't work as expected)
|
||||||
### Keycloak configuration
|
### Keycloak configuration
|
||||||
|
|
||||||
To configure keycloak to work with this bundle, [here](./Resources/docs/keycloak-config-guide.md) is a step by step documentation for a basic configuration of keycloak.
|
To configure keycloak to work with this bundle, [here](./Resources/docs/keycloak-config-guide.md) is a step by step documentation for a basic configuration of keycloak.
|
||||||
@@ -86,5 +106,6 @@ To configure keycloak to work with this bundle, [here](./Resources/docs/keycloak
|
|||||||
| Bundle Version | Symfony Version |
|
| Bundle Version | Symfony Version |
|
||||||
| ------------------------------------------------------|--------------------|
|
| ------------------------------------------------------|--------------------|
|
||||||
| V1.0.1 | >=4.0.0 <5.0.0 |
|
| V1.0.1 | >=4.0.0 <5.0.0 |
|
||||||
| V1.1.0 (uses old authentication systeme with guard) | >=5.0.0 <6.0.0 |
|
| V1.1.* (uses old authentication systeme with guard) | >=5.0.0 <6.0.0 |
|
||||||
| V1.2.0 (uses new authentication systeme) | >=5.3.0 <6.0.0 |
|
| V1.2.* (uses new authentication systeme) | >=5.3.0 <6.0.0 |
|
||||||
|
| V1.3.* | >=6.0.0 <7.0.0 |
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
|||||||
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
|
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
|
||||||
use Symfony\Component\Security\Http\Authenticator\AbstractAuthenticator;
|
use Symfony\Component\Security\Http\Authenticator\AbstractAuthenticator;
|
||||||
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
|
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
|
||||||
use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface;
|
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
|
||||||
use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;
|
use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;
|
||||||
|
|
||||||
class KeycloakBearerAuthenticator extends AbstractAuthenticator
|
class KeycloakBearerAuthenticator extends AbstractAuthenticator
|
||||||
@@ -31,7 +31,7 @@ class KeycloakBearerAuthenticator extends AbstractAuthenticator
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function authenticate(Request $request): PassportInterface
|
public function authenticate(Request $request): Passport
|
||||||
{
|
{
|
||||||
$token = $request->headers->get('Authorization');
|
$token = $request->headers->get('Authorization');
|
||||||
if (null === $token || empty($token)) {
|
if (null === $token || empty($token)) {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace ABEL\Bundle\keycloakBearerOnlyAdapterBundle\Security\User;
|
|||||||
|
|
||||||
use Symfony\Component\Security\Core\User\UserInterface;
|
use Symfony\Component\Security\Core\User\UserInterface;
|
||||||
|
|
||||||
class KeycloakBearerUser implements UserInterface, \Serializable
|
class KeycloakBearerUser implements UserInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
@@ -202,7 +202,7 @@ class KeycloakBearerUser implements UserInterface, \Serializable
|
|||||||
*
|
*
|
||||||
* @return array (Role|string)[] The user roles
|
* @return array (Role|string)[] The user roles
|
||||||
*/
|
*/
|
||||||
public function getRoles()
|
public function getRoles(): array
|
||||||
{
|
{
|
||||||
return $this->roles;
|
return $this->roles;
|
||||||
}
|
}
|
||||||
@@ -270,7 +270,7 @@ class KeycloakBearerUser implements UserInterface, \Serializable
|
|||||||
* @return string the string representation of the object or null
|
* @return string the string representation of the object or null
|
||||||
* @since 5.1.0
|
* @since 5.1.0
|
||||||
*/
|
*/
|
||||||
public function serialize()
|
public function __serialize()
|
||||||
{
|
{
|
||||||
return serialize(array(
|
return serialize(array(
|
||||||
$this->sub,
|
$this->sub,
|
||||||
@@ -293,7 +293,7 @@ class KeycloakBearerUser implements UserInterface, \Serializable
|
|||||||
* @return void
|
* @return void
|
||||||
* @since 5.1.0
|
* @since 5.1.0
|
||||||
*/
|
*/
|
||||||
public function unserialize($serialized)
|
public function __unserialize($serialized)
|
||||||
{
|
{
|
||||||
list (
|
list (
|
||||||
$this->sub,
|
$this->sub,
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ class KeycloakBearerUserProvider implements UserProviderInterface{
|
|||||||
*/
|
*/
|
||||||
public function supportsClass(string $class)
|
public function supportsClass(string $class)
|
||||||
{
|
{
|
||||||
return KeycloakBearerUser::class === $class || is_subclass_of(KeycloakBearerUser, User::class);
|
return KeycloakBearerUser::class === $class || is_subclass_of($class, KeycloakBearerUser::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -100,7 +100,7 @@ class KeycloakBearerUserProvider implements UserProviderInterface{
|
|||||||
'base_uri' => $this->issuer,
|
'base_uri' => $this->issuer,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$response = $client->post('/auth/realms/'.$this->realm.'/protocol/openid-connect/token/introspect', [
|
$response = $client->post('/realms/'.$this->realm.'/protocol/openid-connect/token/introspect', [
|
||||||
'auth' => [$this->client_id, $this->client_secret],
|
'auth' => [$this->client_id, $this->client_secret],
|
||||||
'form_params' => [
|
'form_params' => [
|
||||||
'token' => $accessToken,
|
'token' => $accessToken,
|
||||||
|
|||||||
@@ -12,10 +12,10 @@
|
|||||||
"minimum-stability": "stable",
|
"minimum-stability": "stable",
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=7.2.5",
|
"php": ">=7.2.5",
|
||||||
"symfony/config": "^5.3",
|
"symfony/config": "^6.0",
|
||||||
"symfony/dependency-injection": "^5.3",
|
"symfony/dependency-injection": "^6.0",
|
||||||
"symfony/http-kernel": "^5.3",
|
"symfony/http-kernel": "^6.0",
|
||||||
"symfony/security-bundle": "^5.3",
|
"symfony/security-bundle": "^6.0",
|
||||||
"guzzlehttp/guzzle": "^6.3",
|
"guzzlehttp/guzzle": "^6.3",
|
||||||
"ext-json": "*"
|
"ext-json": "*"
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user