jzohrab / lute

DEPRECATED: LUTE (Learning Using Texts) is a self-hosted web app for learning language through reading, based on Learning with Texts (LWT)
The Unlicense
118 stars 10 forks source link

HTTP Basic Authentication for security #27

Closed 99MengXin closed 1 year ago

99MengXin commented 1 year ago

Is your feature request related to a problem? Please describe. For people who want to have a simple login feature. ! important ! It can only stop regular people to mess up your database, b/c the password is plaintext. Maybe someone can help me to set/hash the password. For now, it's fine for me.

Describe the solution you'd like Just use HTTP Basic Authentication

  1. Add below lines in .env file and change USERNAME as well as PASSWORD, both default values are lute

    # For login Lute
    # You cannot use log out with the HTTP basic authenticator.
    # Even if you log out from Symfony, your browser "remembers" your
    #credentials and will send them on every request.
    # -------------------
    LUTE_USER_USERNAME=lute
    LUTE_USER_PASSWORD=lute
  2. Replace all content in ./config/packages/security.yaml as below

    
    security:
    # https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords
    password_hashers:
        # Uncomment below 1 lines to restore orginal setting
        # Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
    
        # Uncomment below 1 line to use login feature (Http Basic Access)
        Symfony\Component\Security\Core\User\InMemoryUser: plaintext
    # https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider
    providers:
        # Uncomment below 1 lines to restore orginal setting
        # users_in_memory: { memory: null }
    
        # Uncomment below 4 lines to use login feature (Http Basic Access)
        users_in_memory:
            memory:
                users:
                    '%env(LUTE_USER_USERNAME)%': {password: '%env(LUTE_USER_PASSWORD)%', roles: ['ROLE_USER']}
    
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
    
        # TURNING OFF SECURITY FOR PROD.
        # Yes, this looks bad, but Lute is designed to run locally only.
        # There are _no security checks_.
    
        # Uncomment below 3 lines to restore orginal setting
        # prod:
        #     pattern: ^/
        #     security: false
    
        # Uncomment below 4 lines to use login feature (Http Basic Access)
        main:
            lazy: true
            provider: users_in_memory
            http_basic:
                realm: Secured Area
    
            # activate different ways to authenticate
            # https://symfony.com/doc/current/security.html#the-firewall
    
            # https://symfony.com/doc/current/security/impersonating_user.html
            # switch_user: true
    
    # Easy way to control access for large sections of your site
    # Note: Only the *first* access control that matches will be used
    access_control:
        # Uncomment below 1 line to use login feature (Http Basic Access)
         - { path: ^/, roles: ROLE_USER }
    
        # - { path: ^/admin, roles: ROLE_ADMIN }
        # - { path: ^/profile, roles: ROLE_USER }

when@test: security: password_hashers:

By default, password hashers are resource intensive and take time. This is

        # important to generate secure password hashes. In tests however, secure hashes
        # are not important, waste resources and increase test times. The following
        # reduces the work factor to the lowest possible values.
        Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface:
            algorithm: auto
            cost: 4 # Lowest possible value for bcrypt
            time_cost: 3 # Lowest possible value for argon
            memory_cost: 10 # Lowest possible value for argon


3. There is no log out button, so you might use **incognito window** for every time login.

4. For docker user, if you want to change user/password after running docker
4.1 run `docker compose stop`
4.2 amend user/password you want in `.env`
4.3 run `docker compose up`

**Additional context**

<img width="1822" alt="截圖 2023-04-18 16 08 15" src="https://user-images.githubusercontent.com/51739513/232713492-49850f85-1416-4709-97fc-1548d176ac47.png">
jzohrab commented 1 year ago

Hi @99MengXin , thanks for the PR.

One thing I don't want is to force users (especially me) to have to log in all of the time. Would this code change make that happen, or is there a clever way that we can work around it? (e.g., if the USER and PASSWORD are missing from the .env file, don't require a login.) Or, does this merely need to be documented somewhere on the WIKI?

Cheers!

99MengXin commented 1 year ago

Hi @jzohrab ,

  1. The username can't be empty.
  2. You need log in only at the first time, it's difficult to log out actually. That's why we need use incognito window to log in every time. See http - How to log out user from web site using BASIC authentication? - Stack Overflow
jzohrab commented 1 year ago

Got it, thanks. So, what should I do with this info? I wonder if I should just put a note in the wiki, with some comments in the .env.example* files. I don't want to make this the default behaviour for the app, I know that I'll find it annoying. :-)

If you're OK with just wiki, that's super. There might be other possibilities (e.g., a special "APP_ENV=secure" or something in the .env file, and then mucking around with the configuration .yml file, per notes in https://symfony.com/doc/current/configuration.html), but I'm not sure if it will work out.

99MengXin commented 1 year ago

I'm OK with wiki, just let people know there is way to secure.

Users can follow this instruction and add the feature by themself.

jzohrab commented 1 year ago

Thanks very much @99MengXin for getting this started. I simplified the file a bit and committed it to the develop branch, and added notes to the wiki about config (https://github.com/jzohrab/lute/wiki/Security). I'll use this for a bit and see how it goes, and will try it out again when I make release 2.0.1. Thanks!