Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

symfony - How can I swtich authorization method by ENV variable?

I meet an unusual problem. We have a form_login (based on FOS user-bundle). And now we want to change it to hslavich/OneloginSamlBundle for saml auth. But we want to save ability to select an auth method by changing environment vars in kubernetes deployment. We use k8s on prod with pre-build images (implements "bin/console cache:warmup" in composer scripts for generating cache).

I'm implemented an environment variable for switch needed config. Than I generate a switcher like this:

return static function (ContainerConfigurator $container) {
    $isSamlEnabled = getenv('IS_AUTH_SAML_ENABLE');
    if($isSamlEnabled === true) {
        $container->import('security_provider_configs/saml.yml');
    }
    else {
        $container->import('security_provider_configs/ldap.yml');
    }
}; 

But this solution use fixed variable IS_AUTH_SAML_ENABLE, which was is in builded image and can't be changed in kubernetes deployment.

We can add new APP_ENV stage, for difference prod-form and prod-saml, we can build two images like 'v2.123-form' and 'v2.123-saml'. But this will brake all CI/CD in our company. It's very difficult.

Do you know any methods to switch auth method by change env variable?

security.yml like this:

security:
  providers:
    form_usr:
      id: my_service.provider.user
    saml_provider:
      entity:
        class: MyServiceUserModel
        property: username

  firewalls:
    dev:
      pattern: ^/(_(profiler|wdt|error)|css|images|js)/
      security: false
    main:
      pattern: ^/
      saml:
        provider: saml_provider
        user_factory: user_saml_factory
        username_attribute: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name
        persist_user: true
        check_path: /saml/acs
        login_path: /saml/login
      form_login:
        provider: form_usr
        default_target_path: about
        always_use_default_target_path: true
      logout:
        target: /login
      anonymous: true
question from:https://stackoverflow.com/questions/65903402/how-can-i-swtich-authorization-method-by-env-variable

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Disclaimer: I'm not completely certain that this will work, but this case demands some testing on your part. ;o) Please report back if it indeed does work.

As Nico Haase correctly pointed out, your env vars are resolved at cache/compile-time. However, this is a poster case for APP_ENV (which is usually dev on dev systems and prod on production), you could add/use prod_ldap and prod_saml instead of just prod, which absolutely can have implications on your application. (switching a user from one to the other will not work without some hassle or at least re-login) - see https://symfony.com/doc/4.1/configuration/environments.html for some more information about adding more environments. The documentation is for symfony 4.1 so please don't blindly follow the examples. Stuff has changed, but the general idea should still be viable.

For that to work, you would have to adapt config/bundles.php, and possibly src/Kernel.php and maybe even more things, and you probably have to copy some of the env-specific configs ...

Since all caching and container-building is done depending on APP_ENV and the results are written to a APP_ENV-specific cache location, the containers as well as the caches and sessions would reside in different locations - you'd have the same code base and the same project directory but different cache and config dirs. Unless your application is extremely sophisticated and sensitive to this, this should work.

Please note, that depending on how you're changing your APP_ENV, this might absolutely not work. If it's set by the webserver, I'm confident it should.
Please also note, that to put your system live, you will have to do both bin/console cache:clear --env=prod_saml as well as bin/console cache:clear --env=prod_ldap, composer will run the one in .env(.local) automatically - if you even run composer - but you only can have one at the time. You could extend the composer.json to run both cache:clear commands as a post-something script.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...