Accessing JNDI Datasource using Container Managed Authentication Alias in Websphere (Spring + Ibatis/Mybatis) - websphere

I am using WebSphere 8.5.5.18.
As of now I'm using Component-Managed Authentication Alias for my DataSource. But I want to use Container-Managed instead. When I just change the Security settings in Data Sources → Security settings I am getting error in logs. It is unable to fetch records.
Exception Stacktrace:
Check the SQL Statement (preparation failed).
--- Cause: java.sql.SQLException: [jcc][t4][10205][11234][3.72.54] Null userid is not supported. ERRORCODE=-4461, SQLSTATE=42815 DSRA0010E: SQL State = 42815, Error Code = -4,461
at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:97)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
at org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMapClientTemplate.java:212)
at org.springframework.orm.ibatis.SqlMapClientTemplate.queryForObject(SqlMapClientTemplate.java:271)
Basically the database is not being accessed properly when settings are changed from Component-Managed Authentication to Container-Managed Authentication alias.
When I run with Component-Managed Authentication, its working fine.
Does changing security setting to Container Managed Authentication alias, require some other/additional setting/changes? Or do I need to change my underlying Spring ibatis code to make it work?
Any help on configuring/implementing Container-Managed Authentication Alias in websphere would be appreciated.

Container-managed authentication applies when your code (or any third party code that executes upon its behalf) looks up the data source with a resource reference that specifies the resource authentication as container or leaves resource authentication unspecified, in which case it defaults to container.
Component-managed authentication applies when your code (or any third party code that executes upon its behalf) looks up the data source without a resource reference, or uses a resource reference that specifies the resource authentication as application.
Here are some examples of resource references that use container authentication:
// resource injection can be used on a web component (servlet) or ejb component
#Resource(name = "java:comp/env/jdbc/ds1ref", lookup = "jdbc/ds1", authenticationType = Resource.AuthenticationType.CONTAINER)
DataSource ds1;
#Resource(name = "java:comp/env/jdbc/ds2ref", lookup = "jdbc/ds2")
DataSource ds2;
...
// code that looks up one of the above resource references
DataSource ds = InitialContext.doLookup("java:comp/env/jdbc/ds1ref");
Here is an example of a resource reference defined within a web.xml deployment descriptor:
<resource-ref>
<res-ref-name>java:comp/env/jdbc/ds3ref</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<lookup-name>jdbc/ds3</lookup-name>
</resource-ref>
If third party code, such as Spring, is looking up a data source on your behalf and you would like it to use container authentication, you will need to define a resource reference with container managed authentication, such as shown above in the examples, and supply its resource reference name to the third party software in place of however you are doing so currently. If you are unsure where this is done, it might help to search for occurrences of the configured JNDI name of the WebSphere data source within the application.

Related

Spring-boot LDAP - Property 'userDn' not set

I am running a Spring-boot application which authenticates users via our internal LDAP with spring-security-ldap.
By default it binds with LDAP anonymously.
Property 'userDn' not set - anonymous context will be used for read-write operations
But I want the first bind to be with current username.
Where should I specify the userDn attribute?
Thank you for your advice
When using spring ldap maybe you started from one many tutorials on the web but main of them uses embedded ldap server; embdedded server uses ldif file and doesn't need the manager credetials.
When connecting to an external ldap server you need to specify userDn setting it via managerDn method. Here the snippet of code
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.ldapAuthentication().contextSource().managerDn("uid=admin,ou=system")
.managerPassword("secret")
.......
}
Obviously you need to provide also all the other infos like url, port, etc (and userSearchBase like mvreijn told).
I am not the most knowledgeable person regarding Spring-boot, more so regarding LDAP.
That said, your LDAP configuration properties should be mentioned in your application.properties file and are named spring.ldap.*.
They are mentioned in the documentation here.
When initializing your authentication provider, you can pass important properties like the Base DN (root to search from) and the filter using:
.userSearchBase("ou=<your users container>").userSearchFilter("(uid={0})")
Most likely, your search filter will be uid={0} or cn={0}.

NonSqlTransientException in Liberty Server

am facing NonSqlTransientException Null userid not supported while starting the liberty server where my server.xml contain authdata
The authData configuration in Liberty is only for container managed authentication. If you are using application authentication (as is the case for JNDI lookup without resource reference, or if using a resource reference that is set to authentication type of Application), then authData does not apply. If you are using a resource reference with Container authentication, then you can use the authData, but there is an additional configuration step to associate the authData with the dataSource. This can be done in either of the following ways, documented in this knowledge center article.
One option is to configure the containerAuthDataRef of the dataSource to point at the id of the authData element (you'll need to add an id for it if it doesn't have one). Here is an example,
<authData id="myAuth" user="user1" password="pwd1"/>
<dataSource jndiName="jdbc/myDataSource" containerAuthDataRef="myAuth">
<jdbcDriver libraryRef=...
<properties...
</dataSource>
The other option is to specify the authData's id under the authentication-alias in the application's bindings (such as ibm-web-bnd.xml or ibm-ejb-jar-bnd.xml) for the data source. For example, the following bindings are based on the server config from the previous example,
<resource-ref name="java:app/env/jdbc/myDataSourceRef" binding-name="jdbc/myDataSource">
<authentication-alias name="myAuth"/>
</resource-ref>
It should be noted that the former is a default for container authentication that is used in the absence of the latter. So if you specify both ways, then the latter takes precedence and will be used instead.

Spring + Liberty +JNDI +Oracle

I have a server.xml with jndi configuration that works and can connect to database (validated with small program using #Resource), but when I try to use an application that is spring based, I can never login to the database. I am successfully getting the jndi reference, but it just never logs in and gives me invalid username/password.
I have searched this to death on google, and haven't found anything that can point in the right direction.
You should post the specific details about your configuration and resource references. One way to cause the error you are seeing would be to configure a dataSource with the user/password specified only within the default container authdata (dataSource with nested containerAuthData element, or with a containerAuthDataRef specified). When you use #Resource, you are getting container authentication by default, and the user/password would be used. However, if Spring is directly looking up the data source (no resource reference) or specifies a resource reference with application authentication, then the user/password of the default container authdata would not apply. However, if instead you configure user/password on the vendor properties element that is nested under dataSource, then it will reply regardless of the authentication type.
Example of data source configuration where user/password will only be used for container authentication:
<dataSource id="DefaultDataSource" jndiName="jdbc/oracle">
<containerAuthData user="user1" password="pwd1"/>
<jdbcDriver libraryRef="OracleLib"/>
<properties.oracle URL="jdbc:oracle:thin:#//localhost:1521/SAMPLEDB"/>
</dataSource>
Example of data source configuration where user/password apply regardless of whether container or application authentication are used,
<dataSource id="DefaultDataSource" jndiName="jdbc/oracle">
<jdbcDriver libraryRef="OracleLib"/>
<properties.oracle URL="jdbc:oracle:thin:#//localhost:1521/SAMPLEDB" user="user1" password="pwd1"/>
</dataSource>
invalid username/password is an oracle error message, so you may be:
pointing to the wrong DB (where user does not live)
using the wrong user
using the wrong password
Try the connection in SQL Plus, if it works there, then problem in the code/configuration.

Add authoraization in Jmeter load testing with JMeter jms point to point queue

I am using jmeter jms point to point queue for load testing.
But I am getting the following error:
javax.naming.NamingException: Failed to create remoting connection [Root exception is java.lang.RuntimeException: javax.security.sasl.SaslException: Authentication failed: all available authentication mechanisms failed]
I am using jmeter 2.11 version
I add user name and password in jndi properties. But still it is not working. Here is the configuration i am using:
QueueConnectionFactory: RemoteConnectionFactory
initial context factory: org.jboss.naming.remote.client.InitialContextFactory
url : remote://localhost:4447
JNDI Prpperties:
username: ..............
password: ...........
Your Jndi properties seem wrong, check this:
http://docs.oracle.com/cd/E19182-01/820-7853/ghyco/index.html
Login / password props are :
java.naming.security.principal
The identity of the principal for authenticating the caller to the service. For more information, see the Java API documentation for javax.naming.Context.SECURITY_PRINCIPAL.
java.naming.security.credentials
The credentials of the principal for authenticating the caller to the service. For more information, see the Java API documentation for javax.naming.Context.SECURITY_CREDENTIALS.
I have encountered similar problem while using jmeter for solace, hope this help to someone having similar issue.
For solace jms testing need to use jndi properties since there is no place holder for VPN name. JNDI properties file will look something like this:
java.naming.factory.initial=com.solacesystems.jndi.SolJNDIInitialContextFactory
java.naming.provider.url=<IP:port><br>
Solace_JMS_VPN=<VPN Name><br>
java.naming.security.principal=<username><br>
java.naming.security.credentials=<password>
Here the jndi properties has to be packaged as a jar file and placed in the jmeter lib folder in order to be picked at runtime.
jar cvf my-jndi-properties.jar jndi.properties
Hope this helps.

Roles Based Security for EJB deployed on Weblogic

I am working on an EJB application. I have to apply role based security on session bean(EJB3) methods, for which I tried annotating the session bean method with "#RolesAllowed" as below,
For creating User, groups and roles i am using jazn-data.xml as below,
After the deploying the EJB and running the application, security does get applied and throws an exception [EJB:010160]Security Violation: User: 'XXX' has insufficient permission to access EJB
After Adding the weblogic ejb deployment descriptor as below,
<?xml version = '1.0' encoding = 'windows-1252'?>
<weblogic-ejb-jar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.oracle.com/weblogic/weblogic-ejb-jar http://xmlns.oracle.com/weblogic/weblogic-ejb-jar/1.1/weblogic-ejb-jar.xsd"
xmlns="http://xmlns.oracle.com/weblogic/weblogic-ejb-jar">
<weblogic-enterprise-bean>
<ejb-name>ApplicationFacade</ejb-name>
<stateless-session-descriptor/>
<enable-call-by-reference>true</enable-call-by-reference>
</weblogic-enterprise-bean>
<security-role-assignment>
<role-name>PVUser</role-name>
<principal-name>pv</principal-name>
</security-role-assignment>
<security-role-assignment>
<role-name>PRUser</role-name>
<principal-name>pr</principal-name>
</security-role-assignment>
</weblogic-ejb-jar>
It starts working as expected.
My question is related to weblogic ejb deployment descriptor(weblogic-ejb-jar.xml), do I have to make an entry for each user (pricipal-name), each time I am adding a new user or is there a way by which i can map a user-groups?
Also let me know if I have missed any other configuration required to add permissions.
The Answer is yes,
and what you need to do is creating a group named xxx by login to the
weblogic console( modify within the Security Realms panel)
then adding all of the user to the group named xxx
lastly in the weblogic ejb deployment descriptor you just need to
specify the group name as
< principal-name >xxxgroup name < / principal-name >
as a result, every member within the group would share the
permission.

Resources