WildFly LDAP Connection JNDI - java

We are in the process of moving from Glassfish to WildFly. In Glassfish we setup our LDAP server and use it for authentication and we also reference it with JNDI for us within the application for things such as searching users, etc. I am wondering if there is a way to setup the LDAP connection in the standalone.xml file in WildFly for reference via JNDI in the application like we currently do. I have setup LDAP for authentication and that works but I do not know how to reference that connection for use in our application.

In Wildfly you can use Naming Subsystem for binding a Ldap context, in particular External Context Federation binding type:
External Context Federation
Federation of external JNDI contexts, such as a LDAP context, are
achieved by adding External Context bindings to the global bindings
configuration, through the external-context XML element
For example:
<subsystem xmlns="urn:jboss:domain:naming:2.0">
<bindings>
<external-context name="java:global/federation/ldap/example" class="javax.naming.directory.InitialDirContext" module="org.jboss.as.naming" cache="true">
<environment>
<property name="java.naming.factory.initial" value="com.sun.jndi.ldap.LdapCtxFactory" />
<property name="java.naming.provider.url" value="ldap://ldap.example.com:389" />
<property name="java.naming.security.authentication" value="simple" />
<property name="java.naming.security.principal" value="uid=admin,ou=system" />
<property name="java.naming.security.credentials" value="secret" />
</environment>
</external-context>
</bindings>
<remote-naming/>
</subsystem>
Ref: WildFly 8
- Naming Subsystem Configuration
I hope this help.

Related

Multiple AssertionConsumerService in SP with differend 2nd level domains

I am implementing a multitenant application with the spring security saml extention.
I have a Service Provider (SP) for each tenant.
All SPs runs on the same server exposed with SP-specific 2nd level domain:
sp1.myapp.com/myapi/1/
sp1.myapp.com/myapi/2/
In each SP metadata file I have configured the tenant-specific AssertionConsumerService.
When I test the SSO Login, I get a KO on SP side when it gets the response of the Identity Provider (IDP).
On Log side i see only:
ERROR [BaseSAMLMessageDecoder] SAML message intended destination endpoint 'https://sp1.myapp.com/myapi/saml/SSO' did not match the recipient endpoint 'https://default.myapp.com/myapi/saml/SSO'
Where the 'https://default.myapp.com/myapi/saml/SSO' is the URL set as serverName of the load balancer context provider:
<bean id="lbContextProvider" class="org.springframework.security.saml.context.SAMLContextProviderLB" init-method="afterPropertiesSet">
<property name="metadata" ref="metadata" />
<property name="keyManager" ref="keyManager" />
<property name="scheme" value="https" />
<property name="serverName" value="default.myapp.com" />
<property name="contextPath" value="/myapi" />
<property name="serverPort" value="443" />
<property name="includeServerPortInRequestURL" value="true" />
</bean>
Question
In the docs.spring.io/spring-security-saml I see that
Service provider can now define multiple assertion consumer endpoints with same binding
How can I configure it?
Does it conflict with load balancer context provider?
Can I provide multiple AssertionConsumerService with different 2nd level domains without reproduction this conflict?
I already tested:
This question seems to be fixed with the LB, but anyone knows if I can provide multiple serverName to load balancer context provider (maybe with a dynamic pick)?
Disable the checking of the InResponseToField as suggested at ch.13 docs.spring.io/spring-security-saml and for this and this question.
Configure the defaultTargetUrl of the successRedirectHandler (where I am using a custom superclass of org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler) as suggested for this question. In addition this solution is not multitenant.
<bean id="successRedirectHandler" class="org.MySamlAuthenticationSuccessHandler"
init-method="afterPropertiesSet">
<property name="contextPath" value="/myapi" />
<property name="defaultTargetUrl" value="https://default.myapp.com/myapi/saml/SSO"/>
<property name="requireProxyWrapping" value="false"/>
</bean>
Customize SAMLContextProviderLB by extending SamlContextProviderLB.
In custom class, add constructor and initialize with default values.
Override getLocalAndPeerEntity/getLocalEntity/populateLocalEntityId. In each of this method set lbDomain based on domain in requestURL.
above approach worked for me.

How do I add JDBC drivers and configure JDBC Resources in Payara Micro?

What are my options to set up JDBC drivers and resources when using Java EE Payara Micro?
This method combines answers from Mike and Adam Bien via tainos. It involves making a new domain.xml, which is a Payara config file. No application modification is needed if it worked with full Payara. The example below is for PostgreSQL JDBC.
Open payara-micro.jar with an archive manager and extract the file /microdomain.xml.
Open microdomain.xml in a text editor.
If your application was already deployed to a full Payara, you can copy-paste the changes below from the full Payara's domain.xml.
Add right above the line containing </resources>, using your dbname, dbuser, dbpassword, hostname:port and poolname:
<jdbc-connection-pool connection-validation-method="auto-commit" driver-classname="org.postgresql.Driver" res-type="java.sql.Driver" name="poolname" is-connection-validation-required="true" connection-creation-retry-attempts="3" validate-atmost-once-period-in-seconds="60">
<property name="URL" value="jdbc:postgresql://localhost:5432/dbname"></property>
<property name="user" value="dbuser"></property>
<property name="password" value="dbpassword"></property>
</jdbc-connection-pool>
<jdbc-resource pool-name="poolname" jndi-name="jdbc/poolname"></jdbc-resource>
Add right above the line containing </server>:
<resource-ref ref="jdbc/poolname"></resource-ref>
Save and close the text editor.
Start Payara micro from command line, using your paths and filenames. Linux syntax:
java -cp "/opt/jdbc/postgresql.jar:/opt/payara/micro.jar" fish.payara.micro.PayaraMicro --deploy webapp.war --domainConfig microdomain.xml
Add the datasource definition to your web.xml and then add the jar file for the JDBC jar into your WEB-INF/lib. Then deploy the war file as usual to Payara Micro.
<data-source>
<name>java:global/ExampleDataSource</name>
<class-name>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</class-name>
<server-name>localhost</server-name>
<port-number>3306</port-number>
<database-name>mysql</database-name>
<user>root</user>
<password>root</password>
<!-- Example of how to use a Payara specific custom connection pool setting -->
<property>
<name>fish.payara.sql-trace-listeners</name>
<value>com.sun.gjc.util.SQLTraceLogger</value>
</property>
</data-source>
There is a complete example of how to do this on the Payara Examples GitHub repository. See Datasource example on Payara GitHub
You can configure JDBC in a normal domain.xml and supply that to Payara. If you're unsure, you can always take an existing domain.xml and use the JDBC configuration from that.
Payara Micro has a few command line options, one of which allows you to specify an alternative domain.xml file:
java -jar payara-micro.jar --deploy myApp.war --domainConfig mydomain.xml
If you're bootstrapping Payara Micro programmatically, you would use:
setAlternateDomainXML(File alternateDomainXML)
As the accepted answer didn't work for me a figured a different and slightly easier way. You still rely on the custom domain.xml, but the startup command can be simplified:
java -jar /opt/payara/payara-micro.jar --deploy webapp.war --domainConfig domain.xml --addJars /opt/mysql-connector-java-5.1.40-bin.jar
This call doesn't require you to know the Main class.
Adam Bien answered this question in his 19th Airhacks video.
My take, When used with custom resources is best used as an embedded server, in the main we configure the JDBC resources and with maven dependencies we include the needed drivers inside the jar or war files.
One of options is glassfish-resources.xml
<!-- db1 -->
<jdbc-connection-pool
datasource-classname="com.mysql.jdbc.jdbc2.optional.MysqlDataSource" name="db1"
res-type="javax.sql.DataSource"
steady-pool-size="1"
is-connection-validation-required="true"
connection-validation-method="meta-data"
max-pool-size="10">
<property name="password" value="icoder_pwd"/>
<property name="user" value="icoder_user"/>
<property name="databaseName" value="icoder_db"/>
<property name="serverName" value="localhost"/>
<property name="portNumber" value="3310"/>
<property name="zeroDateTimeBehavior" value="convertToNull"/>
</jdbc-connection-pool>
<jdbc-resource pool-name="db1" jndi-name="jdbc/db1"/>
<!-- db2 -->
<jdbc-connection-pool
datasource-classname="com.mysql.jdbc.jdbc2.optional.MysqlDataSource" name="db2"
res-type="javax.sql.DataSource"
steady-pool-size="1"
is-connection-validation-required="true"
connection-validation-method="meta-data"
max-pool-size="10">
<property name="password" value="icoder_pwd"/>
<property name="user" value="icoder_user"/>
<property name="databaseName" value="icoder_db"/>
<property name="serverName" value="localhost"/>
<property name="portNumber" value="3311"/>
<property name="zeroDateTimeBehavior" value="convertToNull"/>
</jdbc-connection-pool>
<jdbc-resource pool-name="db2" jndi-name="jdbc/db2"/>
</resources>
Complete example with entity manager implementation you can find:
https://github.com/igorzg/payara-micro-jpa-multi-tenancy

Tomcat connection pool with MyBatis

I was wondering if anyone has any code examples for setting up a connection pool in Tomcat (7 or later) using MyBatis as the ORM.
I presume I need to add a resource to my context.xml file in my Tomcat conf folder and then link that to MyBatis. I've had a look and any tutorials I have found seem to be Spring specific. Does anyone have a simple tutorial or can they outline the steps required to get this up and running?
There is this old entry in the iBatis FAQ that should still be applicable to myBatis: How do I use a JNDI DataSource with iBATIS in Tomcat?.
You can google for the details to configure a datasource in your Tomcat version, then configure MyBatis as well (it's different than the iBatis configuration):
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="JNDI">
<property name="data_source" value="java:comp/env/jdbc/yourDatasourceName"/>
</dataSource>
</environment>
There are a number of ways you can do this. I am assuming that you mean to implement Tomcat (as opposed to Spring) managed connection pooling. I have tested on MySQl/Spring 4/Mybatis-spring 1.1 stack.
Figure out the connection pooling mechanism you want to implement (C3P0/DBCP etc).
If you want to use your database as a JNDI data source, then you have to declare it as a resource in Tomcat settings. There are a number of ways to do this. You can follow this well written guide Tomcat JNDI connection pooling. I generally add the following entry in context.xml located in the META-INF directory of my app:
<Context>
<Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource" maxTotal="100" maxIdle="30" maxWaitMillis="10000" username="javauser" password="javadude" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/javatest"/>
</Context>
This file is used by Tomcat to invoke its own default connection pool, which in this case would be DBCP 2. You can tweak its settings by adding more parameters (like removeAbandonedOnBorrow=true) in the Resource element above. You should put the driver jar (eg MySQL Connector Jar) of your database in Tomcat's lib folder.
After this, depending on your Mybatis implementation (XML or bean based), you can inject this data source into Mybatis. If you are doing it the bean way, you can do it like this:
<bean id="dbDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/TestDB"/>
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dbDataSource" />
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dbDataSource" />
<property name="typeAliasesPackage" value="com.example.model"/>
<property name="mapperLocations" value="classpath*:*.xml" />
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.example.dao" />
</bean>
MapperScannerConfigurer is necessary because it searches the directories given to it to find mapper xml files. You can also use the old way of defining a mybatis-config.xml file by injecting the file's location in the sqlSessionFactory bean in its configLocation property.

JBoss: Binding values into JNDI in JBoss EAP 6 similar to JNDIBindingServiceMgr

How do I bind an arbitrary string to JNDI in JBoss EAP 6? I used to
do it through org.jboss.naming.JNDIBindingServiceMgr MBean in
previous EAP version.
Is there anything similar to org.jboss.naming.JNDIBindingServiceMgr
in JBoss EAP 6?
We are migrating applications from jboss-5.1.EAP to jboss-eap-6.1.
We need to bind some things into JNDI, so applications can look up
values of environment variables.
Many thanks.
You can do the following:
standalone.xml:
<subsystem xmlns="urn:jboss:domain:naming:1.2">
<bindings>
<simple name="java:global/user" value="newUser"/>
</bindings>
</subsystem>
and in spring context:
<bean class="java.util.Properties">
<constructor-arg>
<map>
<entry key="user">
<jee:jndi-lookup jndi-name="java:global/user" />
</entry>
</map>
</constructor-arg>
</bean>
In your app configuration you can have things in ejb-jar.xml deployment descriptor like
<javaee:env-entry>
<javaee:description>JNDI logging context for this app</javaee:description>
<javaee:env-entry-name>logback/context-name</javaee:env-entry-name>
<javaee:env-entry-type>java.lang.String</javaee:env-entry-type>
<javaee:env-entry-value>our-app-context</javaee:env-entry-value>
</javaee:env-entry>
or, if you prefer to have it in the server standalone.xml, do
<subsystem xmlns="urn:jboss:domain:naming:1.1">
<bindings>
<simple name="my/jndi/key" value="MyJndiValue"/>
</bindings>
</subsystem>
the latter (standalone.xml) is a JBoss 7.1 feature, so available in EAP 6.0. In JBoss AS 7.0, a dummy application needs to be used according to this thread.
What if simply:
InitialContext ctx = new InitialContext();
ctx.bind("varName", "value");
If you use that code inside of a JBoss instance you can bind variables into jndi. Remember to use the correct format for varName to bind the variable in the desired scope.

CXF Web Service JMX Port Assignment

We have many CXF web services running under Tomcat. For each of the services, there is a beans config file, with each one having an entry like the one below. The variable ${JMX.PORT} is replaced with the assigned port at runtime. Each service has a separate port. I have looked everywhere but cannot confirm that this is correct. I do know, however, that having the same port for two or more services causes startup issues. So, I am looking for confirmation that each service should have its own port. Note - When I look at a service remotely using JConsole, with a connection string such as service:jmx:rmi:///jndi/rmi:/192.168.29.35:9912/jmxrmi, I can also see the other services, even though they have different port assignments. That makes no sense, unless there are some kind of shared resources. Can anyone help me to understand this? Thanks!
<bean id="org.apache.cxf.management.InstrumentationManager" class="org.apache.cxf.management.jmx.InstrumentationManagerImpl">
<property name="bus" ref="cxf" />
<property name="enabled" value="true" />
<property name="threaded" value="false" />
<property name="daemon" value="false" />
<property name="usePlatformMBeanServer" value="true"/>
<property name="JMXServiceURL" value="service:jmx:rmi:///jndi/rmi://localhost:${JMX.PORT}/jmxrmi" />
</bean>

Categories

Resources