JBoss/WildFly Security Domain shared across projects - java

This is the problem:
I have a custom security domain that autentificates users in active directory but gets the roles from a file (in future from the DB)
Everything works like a charm per project, however the session is not shared across more than one project, even tho the projects share the same security domain, if the user autentificated in one project it has to autentificate again on the other.
Security Domain definition from standalone.xml
<security-domain name="custom-form-auth" cache-type="default">
<authentication>
<login-module code="ro.test.login.CustomLoginModule" flag="required" module="ro.test.Process-login">
<module-option name="activeDirectory" value="${jboss.server.config.dir}/activeDirectory.properties"/>
</login-module>
</authentication>
</security-domain>
jboss-web.xml
<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
<security-domain>custom-form-auth</security-domain>
<disable-audit>true</disable-audit>
</jboss-web>

For shared authentication across applications you must enable the Single Signon functionality. The Single Signon configuration allows a centralized login configuration for corporate sites that use different Web context.
To enable SSO in JBoss7 you need add the sso option in the web subsystem (SSO is configured per host):
<subsystem xmlns="urn:jboss:domain:web:1.1" default-virtual-server="default-host" native="false">
<connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http"/>
<virtual-server name="default-host" enable-welcome-root="true">
<alias name="localhost"/>
<alias name="example.com"/>
<sso reauthenticate="false"/>
</virtual-server>
</subsystem>
See: https://developer.jboss.org/wiki/JBossAS711WebSSONon-Clustered

Related

How to migrate legacy login module to jaas-realm

I am trying to find a way to migrate our security solution from WildFly 22 to WildFly 26, where the legacy way with custom login modules is no longer supported. I found for example this blog post https://wildfly-security.github.io/wildfly-elytron/blog/jaas-realm/ suggesting to use jaas-realm, but I am not able to configure it to be honest.
What exactly should I do, if I want to migrate this example? This was in earlier versions of WildFly defined like this:
<security-domain name="my-form-auth" cache-type="default">
<authentication>
<login-module name="FirstLoginModule" code="my.first.lm.FirstLoginModule" flag="sufficient">
<module-option name="config.filename" value=".first_lm_props" />
</login-module>
<login-module name="SecondLoginModule" code="my.second.lm.SecondLoginModule" flag="sufficient">
<module-option name="config.filename" value=".second_lm_props" />
</login-module>
</authentication>
</security-domain>
Actual code of these login modules was available to WildFly as a dependency of deployed application.
So far, I managed to set configuration of WildFly 26 like this (with basic scenario - just one login module):
<security-domains>
...
<security-domain name="mySD" default-realm="myJaasRealm" permission-mapper="default-permission-mapper">
<realm name="myJaasRealm"/>
</security-domain>
</security-domains>
<security-realms>
...
<jaas-realm name="myJaasRealm" entry="myEntry" module="my.module.with.lm">
<file path="D:\APP\Wildfly\wildfly-26.0.1.Final\bin\elytron\JAAS-login-module.conf"/>
</jaas-realm>
</security-realms>
....
<http>
<http-authentication-factory name="example-loginconfig-http-auth" security-domain="mySD" http-server-mechanism-factory="global">
<mechanism-configuration>
<mechanism mechanism-name="FORM">
<mechanism-realm realm-name="myJaasRealm"/>
</mechanism>
</mechanism-configuration>
</http-authentication-factory>
</http>
....
<subsystem xmlns="urn:jboss:domain:undertow:12.0" default-server="default-server" default-virtual-host="default-host" default-servlet-container="default" default-security-domain="other" statistics-enabled="${wildfly.undertow.statistics-enabled:${wildfly.statistics-enabled:false}}">
...
<application-security-domains>
<application-security-domain name="other" http-authentication-factory="example-loginconfig-http-auth"/>
</application-security-domains>
</subsystem>
JAAS-login-module.conf:
MyEntry {
my.first.lm.FirstLoginModule sufficient;
};
jboss-web.xml:
<jboss-web>
<context-root>${context-root}</context-root>
<security-domain>other</security-domain>
</jboss-web>
Still, I am not able to get it to work.
<jboss-web>
<context-root>${context-root}</context-root>
<security-domain>mySD</security-domain>
</jboss-web>
In web.xml also you have to configure your realm name like
<login-config>
<auth-method>FORM</auth-method>
<realm-name>myJaasRealm</realm-name>
</login-config>

Using 2authorization realm in Wildfly Elytron Security

I want to user an authentication realm trough ldap. This works fine.
Secondly i want store UserRoles for my application in a Roles tables, this works also fine. (Example below, with an aggregate-realm)
But i dont know how to obtain both roles. Roles from LDAP and from my Roles table together.
What i am missing?
<security-domain name="securtiyDomain" default-realm="my-realm" permission-mapper="default-permission-mapper">
<realm name=jdbc-realm" role-decoder="from-roles-attribute"/>
</security-domain>
<security-realms>
<aggregate-realm name="my-realm" authentication-realm="ldap-realm" authorization-realms="jdbc-realm ldap-realm"/>
<jdbc-realm name="jdbc-realm">
<principal-query .... >
<attribute-mapping>
<attribute to="roles" index="1"/>
</attribute-mapping>
</principal-query>
</jdbc-realm>
<ldap-realm name="ldap-realm" dir-context="ldap-connection" direct-verification="true">
<identity-mapping ...>
<attribute-mapping>
<attribute from="cn" to="Roles" .../>
</attribute-mapping>
<user-password-mapper from="userPassword"/>
</identity-mapping>
</ldap-realm>
<simple-role-decoder name="from-roles-attribute" attribute="roles"/>
Your security-domain configuration does not have aggregate realm my-realm in its list of realms. Try something like below:
<security-domain name="securtiyDomain" default-realm="my-realm" permission-mapper="default-permission-mapper">
<realm name=my-realm" role-decoder="from-roles-attribute"/>
</security-domain>

Wildfly 16: Security domain specified in jboss-web.xml is ignored

Running Wildfly 16, I specify a security domain in my application's WEB-INF/jboss-web.xml as follows:
<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
<security-domain>MyDomain</security-domain>
</jboss-web>
In Wildfly's standalone.xml in the undertow section I specify that security domain as application security domain as follows:
<subsystem xmlns="urn:jboss:domain:undertow:8.0" default-server="default-server" default-virtual-host="default-host" default-servlet-container="default" default-security-domain="other" statistics-enabled="${wildfly.undertow.statistics-enabled:${wildfly.statistics-enabled:false}}">
<buffer-cache name="default"/>
<server name="default-server">
<http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/>
<https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true"/>
<host name="default-host" alias="localhost">
<location name="/" handler="welcome-content"/>
<http-invoker security-realm="ApplicationRealm"/>
</host>
</server>
...
<application-security-domains>
<application-security-domain name="MyDomain" security-domain="OAuth2Domain"/>
</application-security-domains>
Next, in the elytron section I specify the security domain as follows:
<subsystem xmlns="urn:wildfly:elytron:6.0" final-providers="combined-providers" disallowed-providers="OracleUcrypto">
...
<security-domain name="OAuth2Domain" default-realm="OAuth2Realm" permission-mapper="default-permission-mapper">
<realm name="OAuth2Realm"/>
</security-domain>
Of course, also OAuth2Realm is subsequently defined and Wildfly starts without complaint. However, when accessing the application through http, Wildfly always uses the security domain "other" in the legacy security section, rather than my security domain in the elytron section. How can I force Wildfly to use my Elytron security domain?
Found the solution: The application is using programmatic login using a JAAS login context, but this knows only the security domains defined in the legacy security system. To login programmatically against a domain in the elytron system an elytron authentication context must be used, as described in https://docs.jboss.org/author/display/WFLY/Client%20Authentication%20with%20Elytron%20Client.html

JBoss authentication when password is encoded by ARGON2id

I have password encrypted by Argon2id in database.
How can I change my configuration to let JBoss know that it have to use Argon2 to verify password?
standalone.xml
<security-domain name="databaseDomain">
<authentication>
<login-module code="Database" flag="required">
<module-option name="dsJndiName" value="java:/datasources/hotel"/>
<module-option name="principalsQuery" value="select password from users where login=?"/>
<module-option name="rolesQuery" value="SELECT employee.position,'Roles' FROM users, employee WHERE employee.id=users.employeeId and login=?"/>
<module-option name="unauthenticatedIdentity" value="guest"/>
</login-module>
</authentication>
</security-domain>
web.xml
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login.html</form-login-page>
<form-error-page>/error.html</form-error-page>
</form-login-config>
</login-config>
jboss-web.xml
<jboss-web>
<security-domain>databaseDomain</security-domain>
</jboss-web>
I added ARGON2 with
<dependency>
<groupId>de.mkammerer</groupId>
<artifactId>argon2-jvm</artifactId>
<version>2.7</version>
</dependency>
I tried adding to standalone.xml
<module-option name="hashAlgorithm" value="ARGON2id"/>
but it didn't work and I wasn't that suprised about this. My form is calling to j_security_check
You need to implement your own login module, sounds scary, but actually it's not.
Find out which version of Picketbox you're Wildfly is bundled with - look in the modules/system/layers/base/org/picketbox/main directory. I.e. for WF 21 the version of Picketbox is 5.0.3.Final
Add the Picketbox library as a provided-scoped dependency to your project
Implement your custom login module by extending the org.jboss.security.auth.spi.DatabaseServerLoginModule class and overriding the convertRawPassword method - this is where you need to convert the user's input into the Argon2 form
Provide the full class name in the code parameter in your login module configuration in standalone.xml. Wildfly will pick it from your deployment and use your implementation instead of the default one.
This should work.

Configure LDAP access info extracted from Wildlfy standalone.xml in Spring Security

I'm developing a webapp using Spring MVC, Maven and Wildfly. I'm not using the web.xml to configure the datasources. My config is applied through Java classes.
I need to access the LDAP server info (url, base dn, username, password), which is in the standalone.xml located in the Wildfly configuration folder of the server, from the Java Spring Security configuration class. For security issues, I'm not allowed to code the LDAP info in the application.properties file. I don't know how to do it without using the web.xml. Any suggestions?
Here's what I have so far...
--standalone.xml (LDAP Config)
<security-domain name="MYDOMAIN">
<authentication>
<login-module code="LdapExtended" flag="required">
<module-option name="java.naming.factory.initial" value="com.sun.jndi.ldap.LdapCtxFactory"/>
<module-option name="java.naming.provider.url" value="ldap://myurl:000/"/>
<module-option name="java.naming.security.authentication" value="simple"/>
<module-option name="bindDN" value="mybinddn"/>
<module-option name="bindCredential" value="00000000000"/>
<module-option name="baseCtxDN" value="DC=bla,DC=bla,DC=bla"/>
<module-option name="baseFilter" value="(sAMAccountName={0})"/>
<module-option name="rolesCtxDN" value="OU=Ludopatia,DC=iplyc,DC=gov,DC=ar"/>
<module-option name="roleFilter" value="(member={1})"/>
<module-option name="roleAttributeID" value="cn"/>
<module-option name="searchScope" value="ONELEVEL_SCOPE"/>
<module-option name="allowEmptyPasswords" value="false"/>
</login-module>
</authentication>
</security-domain>
--SecurityConfiguration.java
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Value("${ldap.urls}")
private String ldapUrls;
#Value("${ldap.base.dn}")
private String ldapBaseDn;
#Value("${ldap.username}")
private String ldapUsername;
#Value("${ldap.password}")
private String ldapPassword;
#Override
public void configure(AuthenticationManagerBuilder auth) throws Exception{
auth.ldapAuthentication()
.userSearchFilter("sAMAccountName={0}")
.groupSearchBase("ou=Ludopatia")
.groupSearchFilter("member={0}")
.contextSource()
.url(ldapUrls+ldapBaseDn)
.managerDn(ldapUsername)
.managerPassword(ldapPassword);
}
}
--pom.xml (part in which the wildfly-maven-plugin is set)
<plugin>
<groupId>org.wildfly.plugins</groupId>
<artifactId>wildfly-maven-plugin</artifactId>
<version>1.0.1.Final</version>
<configuration>
<jboss-home>${wildfly.home}</jboss-home>
<modules-path>${wildfly.home}/modules</modules-path>
<server-config>standalone.xml</server-config>
<filename>${project.build.finalName}.war</filename>
</configuration>
</plugin>
--application.properties
ldap.urls=ldap://myurl:000/
ldap.base.dn=dc=bla,dc=bla,dc=bla
ldap.username=mybinddn
ldap.password=000000000000
Configured like this, it works perfectly. But I need to remove the LDAP info from the application.properties and directly take it from the standalone.xml, without using the web.xml.
Thanks in advance for your help.
You can directly set these values from WILDFLY console as system properties and they will be automatically populated into the standalone.xml file.
For that, kindly follow the following steps:
Enable the management console by adding an admin user (add-user.bat for Windows/add-user.sh for Linux).
After adding a user, access management console (http://127.0.0.1:9990/management).
It will prompt for username and password. Enter username and password.
Navigate to Configuration -> System properties and add as many as properties you want. They will be displayed in the configuration file.
<system-properties>
<property name="ldap.urls" value="ldap://myurl:000/"/>
<property name="ldap.base.dn" value="dc=bla,dc=bla,dc=bla"/>
<property name="ldap.username" value="mybinddn"/>
<property name="ldap.password" value="000000000000"/>
</system-properties>
To access these properties in your code, you need to access them as system properties such as
String ldapUsername= System.getProperty("ldap.username");
String ldapPassword= System.getProperty("ldap.password");
The only drawback of this approach is that the values of these properties will be visible all the time that's why I suggested vault project.
One more suggestion is to provide the encrypted values for ldap configuration and decrypt them after reading.

Categories

Resources