[[Properties_File_Based_Authentication_Migration]]
= Properties Based Authentication / Authorization

[[picketbox-based-configuration]]
== PicketBox Based Configuration

This migration example assumes a deployed web application is configured
to require authentication using FORM based authentication and is
referencing a PicketBox based security domain using the
UsersRolesLoginModule to load user information from a pair or properties
files.

[[original-configuration]]
=== Original Configuration

A security domain can be defined in the legacy security subsystem using
the following management operations: -

[source, ruby]
----
./subsystem=security/security-domain=application-security:add
./subsystem=security/security-domain=application-security/authentication=classic:add(login-modules=[{code=UsersRoles, flag=Required, module-options={usersProperties=file://${jboss.server.config.dir}/example-users.properties, rolesProperties=file://${jboss.server.config.dir}/example-roles.properties}}])
----

This would result in a security domain definition: -

[source, xml]
----
  <security-domain name="application-security">
    <authentication>
      <login-module code="UsersRoles" flag="required">
        <module-option name="usersProperties" value="file://${jboss.server.config.dir}/example-users.properties"/>
        <module-option name="rolesProperties" value="file://${jboss.server.config.dir}/example-roles.properties"/>
      </login-module>
    </authentication>
  </security-domain>
----

[[intermediate-configuration]]
=== Intermediate Configuration

It is possible to take a previously defined PicketBox security domain
and expose it as an Elytron security realm so it can be wired into a
complete Elytron based configuration, if only properties based
authentication was to be migrated it would be recommended to jump to the
fully migration configuration and avoid the unnecessary dependency on
the legacy security subsystem but for situations where that is not
immediately possible these commands illustrate an intermediate solution.

These steps assume the original configuration is already in place.

The first step is to add a mapping to an Elytron security realm within
the legacy security subsystem.

[source, ruby]
----
./subsystem=security/elytron-realm=application-security:add(legacy-jaas-config=application-security)
----

This results in the following configuration.

[source, xml]
----
  <subsystem xmlns="urn:jboss:domain:security:2.0">
    ...
    <elytron-integration>
      <security-realms>
        <elytron-realm name="application-security" legacy-jaas-config="application-security"/>
      </security-realms>
    </elytron-integration>
    ...
  </subsystem>
----

Within the Elytron subsystem a security domain can be defined which
references the exported security realm and also a http authentication
factory which supports FORM based authentication.

[source, ruby]
----
./subsystem=elytron/security-domain=application-security:add(realms=[{realm=application-security}], default-realm=application-security, permission-mapper=default-permission-mapper)
./subsystem=elytron/http-authentication-factory=application-security-http:add(http-server-mechanism-factory=global, security-domain=application-security, mechanism-configurations=[{mechanism-name=FORM}])
----

And the resulting configuration: -

[source, xml]
----
  <subsystem xmlns="urn:wildfly:elytron:1.0" final-providers="combined-providers" disallowed-providers="OracleUcrypto">
    ...
    <security-domains>
      ...
      <security-domain name="application-security" default-realm="application-security" permission-mapper="default-permission-mapper">
        <realm name="application-security"/>
      </security-domain>
    </security-domains>
    ...
    <http>
      ...
      <http-authentication-factory name="application-security-http" http-server-mechanism-factory="global" security-domain="application-security">
        <mechanism-configuration>
          <mechanism mechanism-name="FORM"/>
        </mechanism-configuration>
      </http-authentication-factory>
      ...
    </http>
    ...
  </subsystem>
----

Finally configuration needs to be added to the Undertow subsystem to map
the security domain referenced by the deployment to the newly defined
http authentication factory.

[source, ruby]
----
./subsystem=undertow/application-security-domain=application-security:add(http-authentication-factory=application-security-http)
----

Which results in: -

[source,xml]
----
  <subsystem xmlns="urn:jboss:domain:undertow:4.0">
    ...
    <application-security-domains>
      <application-security-domain name="application-security" http-authentication-factory="application-security-http"/>
    </application-security-domains>
    ...
  </subsystem>
----

_Note: If the deployment was already deployed at this point the
application server should be reloaded or the deployment redeployed for
the application security domain mapping to take effect._

The following command can then be used to verify the mapping was applied
to the deployment.

[source, ruby]
----
[standalone@localhost:9990 /] ./subsystem=undertow/application-security-domain=application-security:read-resource(include-runtime=true)
{
    "outcome" => "success",
    "result" => {
        "enable-jacc" => false,
        "http-authentication-factory" => "application-security-http",
        "override-deployment-config" => false,
        "referencing-deployments" => ["HelloWorld.war"],
        "setting" => undefined
    }
}
----

The deployment being tested here is 'HelloWorld.war' and the output from
the previous command shows this deployment is referencing the mapping.

At this stage the previously defined security domain is used for it's
LoginModule configuration but this is wrapped by Elytron components
which take over authentication.

[[fully-migrated-configuration]]
=== Fully Migrated Configuration

Alternatively the configuration can be completely defined within the
Elytron subsystem, in this case it is assumed none of the previous
commands have been executed and this is started from a clean
configuration - however if the security domain definition does exist in
the legacy security subsystem that will remain completely independent.

First a new security realm can be defined within the Elytron subsystem
referencing the files referenced previously: -

[source, ruby]
----
./subsystem=elytron/properties-realm=application-properties:add(users-properties={path=example-users.properties, relative-to=jboss.server.config.dir, plain-text=true, digest-realm-name="Application Security"}, groups-properties={path=example-roles.properties, relative-to=jboss.server.config.dir}, groups-attribute=Roles)
----

As before a security domain and http authentication factory can be
defined.

[source, ruby]
----
./subsystem=elytron/security-domain=application-security:add(realms=[{realm=application-properties}], default-realm=application-properties, permission-mapper=default-permission-mapper)
./subsystem=elytron/http-authentication-factory=application-security-http:add(http-server-mechanism-factory=global, security-domain=application-security, mechanism-configurations=[{mechanism-name=FORM}])
----

This results in the following overall configuration.

[source, xml]
----
  <subsystem xmlns="urn:wildfly:elytron:1.0" final-providers="combined-providers" disallowed-providers="OracleUcrypto">
    ...
    <security-domains>
      ...
      <security-domain name="application-security" default-realm="application-properties" permission-mapper="default-permission-mapper">
        <realm name="application-properties"/>
      </security-domain>
    </security-domains>
    <security-realms>
      ...
      <properties-realm name="application-properties" groups-attribute="Roles">
        <users-properties path="example-users.properties" relative-to="jboss.server.config.dir" digest-realm-name="Application Security" plain-text="true"/>
        <groups-properties path="example-roles.properties" relative-to="jboss.server.config.dir"/>
      </properties-realm>
    </security-realms>
    ...
    <http>
      ...
      <http-authentication-factory name="application-security-http" http-server-mechanism-factory="global" security-domain="application-security">
        <mechanism-configuration>
          <mechanism mechanism-name="FORM"/>
        </mechanism-configuration>
      </http-authentication-factory>
      ...
    </http>
    ...
  </subsystem>
----

As before the application-security-domain mapping should be added to the
Undertow subsystem and the server reloaded or the deployment redeployed
as required.

[source, ruby]
----
./subsystem=undertow/application-security-domain=application-security:add(http-authentication-factory=application-security-http)
----

Which results in: -

[source, xml]
----
  <subsystem xmlns="urn:jboss:domain:undertow:4.0">
    ...
    <application-security-domains>
      <application-security-domain name="application-security" http-authentication-factory="application-security-http"/>
    </application-security-domains>
    ...
  </subsystem>
----

At this stage the authentication is the equivalent of the original
configuration however now Elytron components are used exclusively.

[[legacy-security-realm]]
== Legacy Security Realm

[[original-configuration-1]]
=== Original Configuration

A legacy security realm can be defined using the following commands to
load users passwords and group information from properties files.

[source, ruby]
----
./core-service=management/security-realm=ApplicationSecurity:add
./core-service=management/security-realm=ApplicationSecurity/authentication=properties:add(relative-to=jboss.server.config.dir, path=example-users.properties, plain-text=true)
./core-service=management/security-realm=ApplicationSecurity/authorization=properties:add(relative-to=jboss.server.config.dir, path=example-roles.properties)
----

This results in the following realm definition.

[source, xml]
----
  <security-realm name="ApplicationSecurity">
    <authentication>
      <properties path="example-users.properties" relative-to="jboss.server.config.dir" plain-text="true"/>
    </authentication>
    <authorization>
      <properties path="example-roles.properties" relative-to="jboss.server.config.dir"/>
    </authorization>
  </security-realm>
----

A legacy security realm would typically be used to secure either the
management interfaces or remoting connectors.

[[migrated-configuration]]
=== Migrated Configuration

One of the motivations for adding the Elytron based security to the
application server is to allow a consistent security solution to be used
across the server, to replace the security realm the same steps as
described in the previous 'Fully Migrated' section can be followed again
up until the http-authentication-factory is defined.

A legacy security realm can also be used for SASL based authentication
so a sasl-authentication-factory should also be defined.

[source, ruby]
----
./subsystem=elytron/sasl-authentication-factory=application-security-sasl:add(sasl-server-factory=elytron, security-domain=application-security, mechanism-configurations=[{mechanism-name=PLAIN}])
----

[source, xml]
----
  <subsystem xmlns="urn:wildfly:elytron:1.0" final-providers="combined-providers" disallowed-providers="OracleUcrypto">
    ...
    <sasl>
      ...
      <sasl-authentication-factory name="application-security-sasl" sasl-server-factory="elytron" security-domain="application-security">
        <mechanism-configuration>
          <mechanism mechanism-name="PLAIN"/>
        </mechanism-configuration>
      </sasl-authentication-factory>
      ...
    </sasl>
  </subsystem>
----

This can be associated with a Remoting connector to use for
authentication and the existing security realm reference cleared.

[source, ruby]
----
./subsystem=remoting/http-connector=http-remoting-connector:write-attribute(name=sasl-authentication-factory, value=application-security-sasl)
./subsystem=remoting/http-connector=http-remoting-connector:undefine-attribute(name=security-realm)
----

[source,xml]
----
  <subsystem xmlns="urn:jboss:domain:remoting:4.0">
    ...
    <http-connector name="http-remoting-connector" connector-ref="default" sasl-authentication-factory="application-security-sasl"/>
  </subsystem>
----

If this new configuration was to be used to secure the management
interfaces more suitable names should be chosen but the following
commands illustrate how to set the two authentication factories and
clear the existing security realm reference.

[source, ruby]
----
./core-service=management/management-interface=http-interface:write-attribute(name=http-authentication-factory, value=application-security-http)
./core-service=management/management-interface=http-interface:write-attribute(name=http-upgrade.sasl-authentication-factory, value=application-security-sasl)
./core-service=management/management-interface=http-interface:undefine-attribute(name=security-realm)
----

[source, xml]
----
  <management-interfaces>
    <http-interface http-authentication-factory="application-security-http">
      <http-upgrade enabled="true" sasl-authentication-factory="application-security-sasl"/>
      <socket-binding http="management-http"/>
    </http-interface>
  </management-interfaces>
----
