Wildfly 20 - Admin ManagementRealm (security-realm) on ldap SSL - ldap

I configure a wildfly 20 and i have a problem with the ManagementRealm (security-realm) on ldap SSL.
With LDAP, it's OK, but as soon as i switch to ldaps the authentication no longer works.
The login window opens and whatever account I indicate (even a true or false login) I turn back to the "Connect to Management Interface" screen (practically blank).
And I have no errors in any log.
I tried a WildFly 19 and 20, on centos 8.
The trustore does exist, I added it in the startup variable (as well as its password)
Here is an excerpt from my standalone.xml file
<security-realms>
<security-realm name="ManagementRealm">
<authentication>
<local default-user="$local" skip-group-loading="true"/>
<ldap connection="ldap_connection" base-dn="OU=Utilisateurs,DC=org">
<advanced-filter filter="(&(sAMAccountName={0})(memberOf=CN=APP-ADMIN,OU=Utilisateurs,DC=org))"/>
</ldap>
<truststore path="truststore.jks" relative-to="jboss.server.config.dir" keystore-password="XXX" />
</authentication>
<authorization map-groups-to-roles="false">
<properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/>
</authorization>
</security-realm>
<security-realm name="LdapSSLRealm">
<authentication>
<truststore path="truststore.jks" relative-to="jboss.server.config.dir" keystore-password="XXX" />
</authentication>
</security-realm>
</security-realms>
<outbound-connections>
<ldap name="ldap_connection" url="ldaps://serveurad:636" search-dn="user" search-credential="XXX"/>
</outbound-connections>
If anyone has an idea I would appreciate it.

A little late but I believe you have to also reference the security realm (containing the ref to the trust store) in your <outbound-connection />:
<outbound-connections>
<ldap name="ldap_connection" url="ldaps://serveurad:636" search-dn="user" search-credential="XXX" security-realm="LdapSSLRealm"/>
</outbound-connections>

Related

How to verify wildfly web server is using added keystore file for https connection?

I have created a self-signed certificate(public_certificate.crt), private key file(private_key.pem). and these are stored in keystore file keystore.jks.
I have configured the same keystore.jks file in the standalone.xml file of widlfly 10 in two section as:
Section 1:
<security-realm name="UndertowRealm">
<server-identities>
<ssl>
<keystore path="keystore.jks" relative-to="jboss.server.config.dir" keystore-password="changeit" />
</ssl>
</server-identities>
</security-realm>
Section 2:
<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="UndertowRealm" enable http2="true"/>
<host name="default-host" alias="localhost">
<location name="/" handler="welcome-content"/>
<filter-ref name="server-header"/>
<filter-ref name="x-powered-by-header"/>
</host>
</server>
I have restarted the server, now when i am accessing the wildfly url(https://localhost:8443) it is coming as "Not Secure" in the browser url section of chrome.
I am having two question related to it:
With or Without configuring the standalone.xml file with our keystore, chrome is mentioning "Not Secure" in browser URL section. it might be because i am using self-signed certificate. but my question is, how will i know that my self-signed certificate is being used by Wildfly.
Is there any way to avoid "Not Secure" warning and it should be coming as "Lock" symbol in the browser for self-signed certificate.

Authentication fail using LDAP Login Module for Teiid VDB Data Virtualization

we are currently running into issues when configuring LDAP authentication for a deployed VDB, we would like to enter our active directory username and password when authenticating.
We have successful configured LDAP authentication for admin console, but running into errors during server start up.
I have been able to successfully configure authentication for the admin console at hostname:9990. I have done so by with the following changes to Standalone.xml we can provide our active directory user/pass and log in to the admin console.
Below are defined security domain which we are running into issues. And a security realm which is working.
This is the error we are receiving
ERROR [org.jboss.as.connector.subsystems.datasources.AbstractDataSourceService$AS7DataSourceDeployer] (MSC service thread 1-1) Exception during createSubject() for java:/refresh: PBOX000016: Access denied: authentication failed: java.lang.SecurityException: PBOX000016: Access denied: authentication failed
at org.jboss.security.plugins.JBossSecuritySubjectFactory.createSubject(JBossSecuritySubjectFactory.java:84)
at org.jboss.jca.deployers.common.AbstractDsDeployer$1.run(AbstractDsDeployer.java:1086)
at org.jboss.jca.deployers.common.AbstractDsDeployer$1.run(AbstractDsDeployer.java:1081)
at java.security.AccessController.doPrivileged(Native Method) [rt.jar:1.8.0_121]
at org.jboss.jca.deployers.common.AbstractDsDeployer.createSubject(AbstractDsDeployer.java:1080)
at org.jboss.jca.deployers.common.AbstractDsDeployer.deployDataSource(AbstractDsDeployer.java:600)
at org.jboss.jca.deployers.common.AbstractDsDeployer.createObjectsAndInjectValue(AbstractDsDeployer.java:282)
at org.jboss.as.connector.subsystems.datasources.AbstractDataSourceService$AS7DataSourceDeployer.deploy(AbstractDataSourceService.java:318)
at org.jboss.as.connector.subsystems.datasources.AbstractDataSourceService.start(AbstractDataSourceService.java:122)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1980)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1913)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [rt.jar:1.8.0_121]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [rt.jar:1.8.0_121]
at java.lang.Thread.run(Thread.java:745) [rt.jar:1.8.0_121]
This is the security realm which is working when authenticating for the admin panel
<security-realm name="ldap-security-realm">
<authentication>
<ldap connection="ldap-connection" base-dn="dc=main">
<advanced-filter filter="(&(sAMAccountName={0}))"/>
</ldap>
</authentication>
</security-realm>
<outbound-connections>
<ldap name="ldap-connection" url="ldap://hostname:389" search dn="adminusername" search-credential="adminpassword"/>
</outbound-connections>
This is the security domain which we are trying to enable authentication for a deployed VDB
<datasource jndi-name="java:/refresh" pool-name="refresh" enabled="true">
<connection-url>jdbc:teiid:refresh#mm://hostname:31000</connection-url>
<driver>teiid</driver>
<security>
<security-domain>test_ldap_security_domain</security-domain>
</security>
</datasource>
<security-domain name="test_ldap_security_domain">
<authentication>
<login-module code="LdapExtended" flag="sufficient">
<module-option name="java.naming.provider.url" value="ldap://hostname:389" />
<module-option name="java.naming.factory.initial" value="com.sun.jndi.ldap.LdapCtxFactory" />
<module-option name="java.naming.security.authentication" value="simple" />
<module-option name="bindDN" value="adminusername" />
<module-option name="bindCredential" value="adminpassword" />
<module-option name="distinguishedNameAttribute" value="sAMAccountName" />
<module-option name="baseFilter" value="(sAMAccountName={0})" />
<module-option name="baseCtxDN" value="dc=main" />
</login-module>
</authentication>
</security-domain>
<transport name="odata">
<authentication security-domain="test_ldap_security_domain"/>
</transport>
<transport name="jdbc" socket-binding="teiid-jdbc" protocol="teiid">
<authentication security-domain="test_ldap_security_domain"/>
</transport>
<transport name="odbc" socket-binding="teiid-odbc" protocol="pg">
<authentication security-domain="test_ldap_security_domain"/>
<ssl mode="disabled"/>
</transport>
The data source configuration by default during the startup tries to create a minimum number of connections. Since data source is secured based on user credentials and there is no active user during the startup it fails.
Change the data source configuration not to create any connections during the startup.
<pool>
<prefill>false</prefill>
</pool>

Let webservice use SSL

With WildFly 8.2.1, I am trying to make existing webservice (JAX-WS) use SSL, but I haven't seen any use of SSL in quickstarts and the information I was able to google is limited. So far I've added this to web.xml:
<security-constraint>
<display-name>Foo security</display-name>
<web-resource-collection>
<web-resource-name>FooService</web-resource-name>
<url-pattern>/foo/FooService</url-pattern>
<http-method>POST</http-method>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
and this is in my standalone.xml:
<subsystem xmlns="urn:jboss:domain:webservices:1.2">
<wsdl-host>${jboss.bind.address:127.0.0.1}</wsdl-host>
<endpoint-config name="Standard-Endpoint-Config"/>
<endpoint-config name="Recording-Endpoint-Config">
<pre-handler-chain name="recording-handlers" protocol-bindings="##SOAP11_HTTP ##SOAP11_HTTP_MTOM ##SOAP12_HTTP ##SOAP12_HTTP_MTOM">
<handler name="RecordingHandler" class="org.jboss.ws.common.invocation.RecordingServerHandler"/>
</pre-handler-chain>
</endpoint-config>
<client-config name="Standard-Client-Config"/>
</subsystem>
but apparently that's not enough; when I look into standalone/data/wsdl/foo.ear/foo.war/FooService/Bar.wsdl I see:
<service name="FooService">
<port binding="foowsb:FooBinding" name="FooBinding">
<soap:address location="http://localhost:8080/foo/FooService"/>
</port>
</service>
Note that in the EAR/WAR, the soap:address.location is filled just with a placeholder (I suppose that the value is ignored).
I've found some info about setting up security realm, and creating the self-signed certificate using keytool (which I did), but I completely miss how this should be linked together.
I've also tried to setup wsdl-uri-scheme=https, but this is supported only in later versions of CXF.
Seems that the soap:address.location value is not ignored when it's being replaced, since changing that from REPLACE_WITH_ACTUAL_URL to https://REPLACE_WITH_ACTUAL_URL did the trick - now the service got exposed on https://localhost:8443.
There is a couple of more steps I had to do in standalone.xml: in undertow, add https-listener:
<https-listener name="secure" socket-binding="https" security-realm="SslRealm"/>
define the SslRealm:
<security-realm name="SslRealm">
<server-identities>
<ssl>
<keystore path="foo.keystore" relative-to="jboss.server.config.dir" keystore-password="foo1234" alias="foo" key-password="foo1234"/>
</ssl>
</server-identities>
<authentication>
<truststore path="foo.truststore" relative-to="jboss.server.config.dir" keystore-password="foo1234"/>
</authentication>
</security-realm>
Note that I reuse the same keystore for server and clients here. And since my clients are ATM in the same WF node during development, I had to setup the client-side part there, too:
<system-properties>
<property name="javax.net.ssl.trustStore" value="${jboss.server.config.dir}/foo.keystore"/>
<property name="javax.net.ssl.trustStorePassword" value="foo1234"/>
<property name="org.jboss.security.ignoreHttpsHost" value="true"/>
</system-properties>
The last property should be replaced in WF 9+ with cxf.tls-client.disableCNCheck.

JBoss Wildfly - Authentication of Web App against LDAP

I have a security domain defined in jboss-web.xml as below
<jboss-web>
<security-domain>java:/jaas/my_ldap_security_domain</security-domain>
<disable-audit>true</disable-audit>
</jboss-web>
I also have defined inside my standalone.xml
<subsystem xmlns="urn:jboss:domain:security:1.2">
<security-domains>
<security-domain name="my_ldap_security_domain" cache-type="default">
<authentication>
<login-module code="LdapExtended" flag="sufficient">
<module-option name="java.naming.factory.initial" value="com.sun.jndi.ldap.LdapCtxFactory"/>
<module-option name="java.naming.provider.url" value="ldaps://xxx.xxx.xxx.xxx:yyyy"/>
<module-option name="java.naming.security.authentication" value="simple"/>
<module-option name="bindDN" value="temp#my.domain"/>
<module-option name="bindCredential" value="mypass"/>
<module-option name="baseCtxDN" value="DC=my,DC=domain"/>
<module-option name="baseFilter" value="(uid={0})"/>
<module-option name="rolesCtxDN" value="DC=my,DC=domain"/>
<module-option name="roleFilter" value="(uniquemember={1})"/>
<module-option name="roleAttributeID" value="cn"/>
<module-option name="searchScope" value="SUBTREE_SCOPE"/>
<module-option name="roleRecursion" value="0"/>
<module-option name="allowEmptyPasswords" value="true"/>
</login-module>
</authentication>
</security-domain>
</security-domains>
</subsystem>
My only realms present on my standalone.xml are
<security-realms>
<security-realm name="ManagementRealm">
<authentication>
<local default-user="$local" skip-group-loading="true"/>
<properties path="mgmt-users.properties" relative-to="jboss.server.config.dir"/>
</authentication>
<authorization map-groups-to-roles="false">
<properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/>
</authorization>
</security-realm>
<security-realm name="ApplicationRealm">
<authentication>
<local default-user="$local" allowed-users="*" skip-group-loading="true"/>
<properties path="application-users.properties" relative-to="jboss.server.config.dir"/>
</authentication>
<authorization>
<properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
</authorization>
</security-realm>
</security-realms>
I did not mention it before because i presumed that this security realms were meant to authenticate the application server console access. Sorry for that.
My doubt is how to create a jsf2 login page to authenticate against what is defined above. I read a lot of articles about but still in the same place beacause most articles use a fake authentication as example (comparing with static strings instead of showing how to consult LDAP server).
Can anyone help me?
i presumed that this security realms were meant to authenticate the application server console access
You're partially correct there. The name="ManagementRealm" does indeed specify a realm config for accessing admin functions. name="ApplicationRealm" would be the attribute to specify for securing a web application
Your current realm config is missing some things necessary for LDAP authentication. I presume you're already familiar with the login-form configuration in web.xml. Your realm configuration should look something like the following, an excerpt from the Wildfly 8 Realm Configuration Manual:
<management>
  <security-realms>
    <security-realm name="ApplicationRealm">
      <authentication>
        <ldap connection="EC2" base-dn="CN=Users,DC=darranl,DC=jboss,DC=org">
          <username-filter attribute="sAMAccountName" />
        </ldap>
      </authentication>
    </security-realm>
 
  </security-realms>
</management>
Where the <ldap> tag specifies that your lookup is against an LDAP server. Beyond this, you only need follow the standard auth methods for a JavaEE application.
The takeaway from this should be that web application security within JavaEE generally takes the same approach of
Setting up a realm (App-server specific)
Setting up security constraints in web.xml (uniform across all JavaEE applications)
Implementing a login method (Configuration or Programmatic)
Related
Java EE 6 Programmatic security, glassfish and JDBC realm
How to properly logout of a Java EE 6 Web Application after logging in
Performing user authentication in Java EE / JSF using j_security_check

When using Basic Authentication for war deployed in WildFly, getUserPrincipal returns null

I have been attempting to get a simple Basic Authentication example working with WildFly 8.1.0, immutant, and friend. I'm willing to post any code desired, but I'm not sure what would be needed at this point. For now, I'll assume my standalone.xml, web.xml, and jboss-web.xml all contain the correct data -- that may not be the case, but for now I'll just dive in to the problem.
I have an application with a simple /test resource. I've deployed it on WildFly and use Basic Authentication to attempt to access it. Also, I've checked my application-roles.properties and application-users.properties files and they seem fine.
When I attempt to log in, I see the following trace from WildFly:
14:30:36,681 TRACE [org.jboss.security] (default task-1) PBOX000210:
defaultLogin, login context:
javax.security.auth.login.LoginContext#4c89fc2c, subject:
Subject(1313538088).principals=org.jboss.security.SimplePrincipal#99148614(tester-na)org.jboss.security.SimpleGroup#83654093(Roles(members:elm-nss-admin))org.jboss.security.SimpleGroup#83654093(CallerPrincipal(members:tester-na))
The user is tester-na and you can see that it is a member of elm-nss-admin.
When I use a bad password, WildFly catches it and my application never does any check. However, when I sent the correct password the above trace is logged and it calls my authentication handler.
The problem is that my authentication handler fails because a call to getUserPrincipal() returns NULL. The resource is protected, here are my security constraints:
<security-constraint>
<web-resource-collection>
<web-resource-name>Protected Resources</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>*</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>
</security-constraint>
When I use LDAP, this isn't a problem. I think it's because LDAP supplied a certificate and WildFly passes up the cookie.
But with Basic Auth, I'm not getting a cookie, I won't barf the debug output unless requested, it's quite verbose, but the relevant bits are: :cookies {}, :context , :session nil
I'm guessing that getUserPrincipal() fails because I'm still in the act of authenticating?
So, any ideas on how I can get the user data/permissions from WildFly so friend can be passed the proper data to authenticate/authorize with?
#
Update: I was able to create a simple application with the same XML files I'm using for the production app and it isn't failing. For interest, and those who use stackoverflow for answers as much as I do, here are the relevant parts:
From standalone.xml in security-realms:
<security-realm name="ApplicationRealm">
<authentication>
<local default-user="$local" allowed-users="*"/>
<properties path="application-users.properties" relative-to="jboss.server.config.dir"/>
</authentication>
<authorization>
<properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
</authorization>
</security-realm>
and in <subsystem xmlns="urn:jboss:domain:security:1.2"> I have:
<security-domain name="other" cache-type="default">
<authentication>
<login-module code="Remoting" flag="optional">
<module-option name="password-stacking" value="useFirstPass"/>
</login-module>
<login-module code="RealmDirect" flag="required">
<module-option name="password-stacking" value="useFirstPass"/>
</login-module>
</authentication>
</security-domain>
<security-domain name="jboss-web-policy" cache-type="default">
<authorization>
<policy-module code="Delegating" flag="required"/>
</authorization>
</security-domain>
<security-domain name="jboss-ejb-policy" cache-type="default">
<authorization>
<policy-module code="Delegating" flag="required"/>
</authorization>
</security-domain>
In my web.xml file (in the war-resources/WEB-INF folder):
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>ApplicationRealm</realm-name>
</login-config>
The jboss.xml file, in the same directory is:
<jboss-web>
<context-root></context-root>
<security-domain>other</security-domain>
</jboss-web>
Since these settings are working with my simple application, I'll start looking for something project specific as to why WildFly isn't giving me the user in my production code.
Any helpful suggestions would be greatly appreciated. Even just a suggestion as to where to start looking.
#
Problem solved. Turns out the user was being logged out before I was attempting to authorize access to a specific resource. :P
Steven solved the problem himself:
Problem solved. Turns out the user was being logged out before I was
attempting to authorize access to a specific resource. :P