oracle / weblogic-deploy-tooling

WebLogic Deploy Tooling
https://oracle.github.io/weblogic-deploy-tooling/
Universal Permissive License v1.0
152 stars 90 forks source link

Improve support for policies #1545

Closed tdferreira closed 4 months ago

tdferreira commented 5 months ago

Hello,

As pointed out in https://github.com/oracle/weblogic-deploy-tooling/issues/1496#issuecomment-2040329919, I'm opening this issue to request improvement in the support for policies within WDT.

When using, for example, the oracle weblogic 12 dev docker image: container-registry.oracle.com/middleware/weblogic:12.2.1.4-dev-ol8 it already has a JNDI Policy with Resource ID type=<jndi> defined by default. Basically, this exists already in the Root Level:

    WLSPolicies:
        JNDI:
            ResourceID: 'type=<jndi>'
            Policy: 'Grp(everyone)'

If I try to create my domain with this:

    WLSPolicies:
        MyJNDIPolicy:
            ResourceID: 'type=<jndi>'
            Policy: 'Rol(Deployer,Admin,Monitor,Operator)|Grp(my_user_group)'

I get the following error:

19.58 SEVERE Messages:
19.58 
19.58         1. WLSDPLY-12601: The policy MyJNDIPolicy is invalid because the ResourceID attribute value type=<jndi> matches built-in policy ResourceID field value with a policy of Grp(everyone)
19.58         2. WLSDPLY-20001: createDomain did not complete the operation because validation failed
19.58         3. WLSDPLY-12409: createDomain failed to create the domain: createDomain did not complete the operation because validation failed
19.58 
19.58 Total:   SEVERE :    3  WARNING :    0

It would be good if we could have an extra parameter that would tell what to do if there's an existing policy. Something like:

    WLSPolicies:
        MyJNDIPolicy:
            ResourceID: 'type=<jndi>'
            Policy: 'Rol(Deployer,Admin,Monitor,Operator)|Grp(my_user_group)'
            **ReplaceIfExists: true|false**

Also, if we have multiple realms, how can we specify for which realm the policy is? it would be good if we could also have a parameter for that. Something like:

    WLSPolicies:
        MyJNDIPolicy:
            ResourceID: 'type=<jndi>'
            Policy: 'Rol(Deployer,Admin,Monitor,Operator)|Grp(my_user_group)'
            Realm: myrealm
            ReplaceIfExists: true|false

Would it also be possible that you could enhance WDT in order to use something like the WebLogic Remote Console extension to make WDT able to use the Discovery Domain Tool to extract the users, groups, policies, credential mappings, etc?

Can you please consider these improvements? Thanks

robertpatrick commented 5 months ago

@tdferreira

Also, if we have multiple realms, how can we specify for which realm the policy is?

As I said before, I do not believe this is even possible. We are copying/updating an LDIFT file with a well-known name into the $DOMAIN_HOME/security directory that the Admin Server will load on first start. As far as I know, this is loaded into the embedded LDAP server without any accommodation for multiple security realms. Feel free to peruse the $ORACLE_HOME/wlserver/server/lib/XACMLAuthorizerInit.ldift file that we use as the starting point and let me know if you figure out how to make it work without modifying WLS proper.

Would it also be possible that you could enhance WDT in order to use something like the WebLogic Remote Console extension to make WDT able to use the Discovery Domain Tool to extract the users, groups, policies, credential mappings, etc?

It is certainly possible to export data from the various built-in providers in online mode (no need to use the Remote Console extension to accomplish this) but trying to translate this data into model entries is a hard problem.

If you just want to export/import internal security provider data between domains, this is certainly possible with simple WLST scripts that treat the exported/imported data as a black box. For example, to export data from the DefaultAuthenticator:

from java.util import Properties

connect('weblogic', 'welcome1', 't3s://localhost:9002')
domain_name = get('Name')

default_realm_path = '/SecurityConfiguration/%s/DefaultRealm' % domain_name
default_realms = ls(default_realm_path, returnType='c', returnMap='true')
if default_realms is None or len(default_realms) != 1:
    print('Failed to determine the default realm name')
    exit(1)
realm_name = default_realms[0]

default_authenticator_path = \
    '/SecurityConfiguration/%s/Realms/%s/AuthenticationProviders/DefaultAuthenticator' % (domain_name, realm_name)

default_authenticator_mbean = cd(default_authenticator_path)
constraints = Properties()

default_authenticator_mbean.exportData('DefaultAtn', '/Users/rpatrick/tmp/users/DefaultAuthenticator_export.ldift', constraints)
disconnect()

and to export that data into another domain:

from java.util import Properties

connect('weblogic', 'welcome1', 't3s://localhost:9002')
domain_name = get('Name')

default_realm_path = '/SecurityConfiguration/%s/DefaultRealm' % domain_name
default_realms = ls(default_realm_path, returnType='c', returnMap='true')
if default_realms is None or len(default_realms) != 1:
    print('Failed to determine the default realm name')
    exit(1)
realm_name = default_realms[0]

default_authenticator_path = \
    '/SecurityConfiguration/%s/Realms/%s/AuthenticationProviders/DefaultAuthenticator' % (domain_name, realm_name)

default_authenticator_mbean = cd(default_authenticator_path)
constraints = Properties()

default_authenticator_mbean.importData('DefaultAtn', '/Users/rpatrick/tmp/users/DefaultAuthenticator_export.ldift', constraints)
disconnect()

Other built-in provider MBeans also support the exportData() and importData() functions that work in a similar way. If this is what you want/need, it seems like you have everything you need to write the WLST script(s) to do this yourself without needing us to try to add the exported data into the WDT model. See the WebLogic Server Security MBeans Reference docs.

Screenshot 2024-04-05 at 5 27 55 PM

robertpatrick commented 5 months ago

@tdferreira We will use this Issue only for the enhancement to allow you to overwrite Built-in policies (which is not a great practice and could easily lead to situations where the domain does not start or does not function properly). We are actively working on this an hope to provide this in WDT 4.0.1.

The support for multiple realms is simply not possible due to the fact that the Admin Server consumes the LDIFT files on initial startup and only does this for the currently active realm.

The support for discovering security data is something we are willing to investigate. If you want to track our progress, feel free to file a separate issue.

tdferreira commented 5 months ago

Thank you @robertpatrick for the detailed explanation including the scripts. Looking forward for the enhancement.