# Development security

Tip

See [Permissions](https://doc.ibexa.co/en/latest/permissions/permissions/index.md) for information about the permissions system in Ibexa DXP.

Security checklist

See the [Security checklist](https://doc.ibexa.co/en/latest/infrastructure_and_maintenance/security/security_checklist/index.md) for a list of security-related issues you should take care of before going live with a project.

## Symfony authentication

To use Symfony authentication with Ibexa DXP, use the following configuration (in `config/packages/security.yaml`):

```
security:
    firewalls:
        ibexa_front:
            pattern: ^/
            user_checker: Ibexa\Core\MVC\Symfony\Security\UserChecker
            anonymous: ~
            form_login:
                require_previous_session: false
            logout: ~
```

And in `config/routes.yaml`:

```
login:
    path: /login
    defaults: { _controller: Ibexa\Core\MVC\Symfony\Controller\SecurityController::loginAction }
login_check:
    path: /login_check
logout:
    path: /logout
```

Note

You can fully customize the routes and/or the controller used for login. However, remember to match `login_path`, `check_path` and `logout.path` from `security.yaml`.

See [security configuration reference](https://symfony.com/doc/7.4/reference/configuration/security.html) and [standard login form documentation](https://symfony.com/doc/7.4/security.html#form-login).

### Authentication using Symfony Security component

Authentication is provided by the Symfony Security component.

[Native and universal `form_login`](https://symfony.com/doc/7.4/security.html#form-login) is used, in conjunction with an extended `DaoAuthenticationProvider` (DAO stands for *Data Access Object*), the `RepositoryAuthenticationProvider`. Native behavior of `DaoAuthenticationProvider` has been preserved, making it possible to still use it for pure Symfony applications.

#### Security controller

A `SecurityController` is used to manage all security-related actions and is thus used to display the login form. It follows all standards explained in [Symfony security documentation](https://symfony.com/doc/7.4/security.html#form-login).

The base template used is [`Security/login.html.twig`](https://github.com/ibexa/core/blob/main/src/bundle/Core/Resources/views/Security/login.html.twig).

The layout used by default is `%ibexa.content_view.viewbase_layout%` (empty layout) but can be configured together with the login template:

```
ibexa:
    system:
        my_siteaccess:
            user:
                layout: layout.html.twig
                login_template: user/login.html.twig
```

##### Redirection after login

By default, Symfony redirects to the [URI configured in `security.yaml` as `default_target_path`](https://symfony.com/doc/7.4/reference/configuration/security.html). If not set, it defaults to `/`.

#### Remember me

It's possible to use the "Remember me" functionality. Refer to the [Symfony cookbook on this topic](https://symfony.com/doc/7.4/security/remember_me.html).

If you want to use this feature, you must at least extend the login template to add the required checkbox:

```
{% extends "@IbexaCore/Security/login.html.twig" %}

{% block login_fields %}
    {{ parent() }}
    <input type="checkbox" id="remember_me" name="_remember_me" checked />
    <label for="remember_me">Keep me logged in</label>
{% endblock %}
```

#### Login handlers / SSO

Symfony provides native support for [multiple user providers](https://symfony.com/doc/7.4/security/user_providers.html). This makes it easy to integrate any kind of login handlers, including SSO and existing third-party bundles (for example, [FR3DLdapBundle](https://github.com/Maks3w/FR3DLdapBundle), [HWIOauthBundle](https://github.com/hwi/HWIOAuthBundle), [FOSUserBundle](https://github.com/FriendsOfSymfony/FOSUserBundle), [BeSimpleSsoAuthBundle](https://github.com/BeSimple/BeSimpleSsoAuthBundle), and more).

See [Authenticating a user with multiple user provider](https://doc.ibexa.co/en/latest/users/user_authentication/#authenticate-user-with-multiple-user-providers) for more information.

## JWT authentication

To use [JWT authentication](https://www.jwt.io/) with Ibexa DXP, in the provided `config/packages/lexik_jwt_authentication.yaml` file, modify the existing configuration by setting `authorization_header` to `enabled`:

```
lexik_jwt_authentication:
    secret_key: '%env(APP_SECRET)%'
    encoder:
        signature_algorithm: HS256
    # Disabled by default, because Page builder uses a custom extractor
    token_extractors:
        authorization_header:
            enabled: true
        cookie:
            enabled: false
        query_parameter:
            enabled: false
```

You also need a new Symfony firewall configuration for REST and/or GraphQL APIs. It's already provided in `config/packages/security.yaml`, you only need to uncomment it:

```
security:
    firewalls:
        ibexa_jwt_rest:
            request_matcher: Ibexa\Rest\Security\JWTTokenCreationRESTRequestMatcher
            user_checker: Ibexa\Core\MVC\Symfony\Security\UserChecker
            stateless: true
            provider: ibexa
            json_login:
                check_path: ibexa.rest.create_token
                username_path: JWTInput.username
                password_path: JWTInput.password
                success_handler: lexik_jwt_authentication.handler.authentication_success
                failure_handler: lexik_jwt_authentication.handler.authentication_failure

        ibexa_jwt_rest.api:
            request_matcher: Ibexa\Rest\Security\AuthorizationHeaderRESTRequestMatcher
            user_checker: Ibexa\Core\MVC\Symfony\Security\UserChecker
            provider: ibexa
            stateless: true
            jwt: ~

        ibexa_jwt_graphql:
            request_matcher: Ibexa\GraphQL\Security\NonAdminGraphQLRequestMatcher
            provider: ibexa
            stateless: true
            jwt: ~
```

Finish the setup by generating a [PEM encoded key pair](https://symfony.com/bundles/LexikJWTAuthenticationBundle/2.x/index.html#generate-the-ssl-keys) by using the command:

```
php bin/console lexik:jwt:generate-keypair
```

The generated key pair will be stored in the `config/jwt`directory.

Ibexa Cloud

To generate and store the tokens on Ibexa Cloud, define the `config/jwt` directory as a volume in the `.platform.app.yaml` file. In 3-node cluster setups, ensure that the key pair is the same on all 3 servers. You can use a network share, or use a local mount and manually copy the key pair between the servers.
