I'm trying to connect to a JBoss MBean, but am getting blocked due to authentication failures.
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
env.put(Context.PROVIDER_URL, "jnp://"+testIP+":"+testPort);
env.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
env.put(Context.SECURITY_PRINCIPAL, "admin");
env.put(Context.SECURITY_CREDENTIALS, "admin");
InitialContext ic = new InitialContext(env);
RMIAdaptor server = (RMIAdaptor) ic.lookup("jmx/invoker/RMIAdaptor");
// Get the MBeanInfo for the JNDIView MBean
ObjectName name = new ObjectName("my.service:service=MyBean");
MBeanInfo info = server.getMBeanInfo(name);
Everything seems to behave fine in terms of connection until the last line when I get:
java.lang.SecurityException: Failed to authenticate principal=null, securityDomain=jmx-console
at org.jboss.jmx.connector.invoker.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:97)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:88)
at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:659)
at org.jboss.invocation.jrmp.server.JRMPProxyFactory.invoke(JRMPProxyFactory.java:179)
:
:
The security domain is configured to use JAAS (in the jmx-invoker-service.xml):
<interceptor code="org.jboss.jmx.connector.invoker.AuthenticationInterceptor"
securityDomain="java:/jaas/jmx-console"/>
And the user is defined in jmx-console-users.properties properly.
It appears to me that the principal is simply not being read properly. Does JBoss use something other than Context.SECURITY_PRINCIPAL/CREDENTIALS? It appears from Their Naming Documentation that they do not, but why is this failing then?
Many Thanks,
-C
Try setting you initial context factory like this:
env.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.security.jndi.LoginInitialContextFactory");
Related
What is the standard way to connect to Mules JMX output through a standard java program,
I'm trying something like this but looking at the source of Mules SimplePasswordJmxAuthenticator, I need to supply auth tokens to mule so perhaps there is a better lib to use for sending jmx requests?
url1 = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:1198/server");
JMXConnector jmxc = JMXConnectorFactory.connect(url1);
I'm not familiar with the details of Mule's JMX server, but here's how you could add credentials to your code snippet:
url1 = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:1198/server");
String[] credentials = new String[]{"myusername", "mypassword"};
Map<String, Object> env = new HashMap<String, Object>(1);
env.put(javax.management.remote.JMXConnector.CREDENTIALS, credentials);
JMXConnector jmxc = JMXConnectorFactory.connect(url1, env);
That's the standard JMXRemoting way of doing it. Perhaps it will work for you.
We have an issue in our environment when using Websphere to attempt to connect to an external system with HttpClient 4.x (current version is 4.2.1). Connecting to the external system is fine with their certificate being installed in Websphere with no additional configuration of HttpClient. However, when they enabled mutual authentication, it no longer works and we get a SSLPeerUnverifiedException exception:
javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated,
at com.ibm.jsse2.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:105),
at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:128),
at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:572),
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:180),
at org.apache.http.impl.conn.ManagedClientConnectionImpl.open(ManagedClientConnectionImpl.java:294),
at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:640),
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:479),
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906),
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:1066),
I was provided the following code sample, and I was wondering if there's any way to configure HttpClient to use an explicit alias like this code sample does. I've tried to find good documentation on using SSL mutual authentication with HttpClient 4 and haven't been able to find much.
Here's the code sample:
private HttpURLConnection getConnection(String server, String machine,
String port) throws Exception {
URL u = new URL(server);
HttpsURLConnection connection = (HttpsURLConnection) u.openConnection();
String alias = "CellDefaultSSLSettings";
final HashMap connectionInfo = new HashMap();
connectionInfo.put(JSSEHelper.CONNECTION_INFO_DIRECTION,
JSSEHelper.DIRECTION_OUTBOUND);
connectionInfo.put(JSSEHelper.CONNECTION_INFO_REMOTE_HOST, machine);
connectionInfo.put(JSSEHelper.CONNECTION_INFO_REMOTE_PORT, port);
javax.net.ssl.SSLSocketFactory sslFact = JSSEHelper.getInstance()
.getSSLSocketFactory(alias, connectionInfo, null);
connection.setSSLSocketFactory(sslFact);
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestMethod("POST");
return connection;
}
Basically, how do I make HttpClient use "CellDefaultSSLSettings"?
Fundamentally this problem has nothing to do with HttpClient. HttpClient can be configured to establish HTTPS connections using any custom SSLContext or SSLSocketFactory instance. This is basically about how to use JSSE APIs to configure SSLContext in the right way. In your particular case JSSEHelper does all the hard work for you.
// JSSE socket factory
javax.net.ssl.SSLSocketFactory jssesf = JSSEHelper.getInstance().getSSLSocketFactory(alias, connectionInfo, null);
// HC socket factory
SSLSocketFactory hcsf = new SSLSocketFactory(jssesf, SSLSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
This will give a connection socket factory that can be registered with the connection manager.
HttpClient 4.3 also comes with SSLContextBuilder class which can be used to assemble custom SSL configurations using fluid builder API.
https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/conn/ssl/SSLContextBuilder.java
oleg's answer helped me out.
What I did was extend the DefaultHttpClient, and each constructor takes a String argument for the destination URL and calls a method setupScheme:
private void setupScheme(final String url) throws Exception {
Scheme scheme = new Scheme("https", 443, retrieveWebsphereSSLConnectionFactory(url));
getConnectionManager().getSchemeRegistry().register(scheme);
}
The method retrieveWebsphereSSLConnectionFactory essentially combines the code from the sample with the code oleg provided:
private SchemeSocketFactory retrieveWebsphereSSLConnectionFactory(final String url)
throws SSLException, URISyntaxException {
final String alias = "CellDefaultSSLSettings";
final HashMap<String, String> connectionInfo = new HashMap<String, String>();
connectionInfo.put(JSSEHelper.CONNECTION_INFO_DIRECTION, JSSEHelper.DIRECTION_OUTBOUND);
connectionInfo.put(JSSEHelper.CONNECTION_INFO_REMOTE_HOST,
URIUtils.extractHost(new URI(url)).getHostName());
connectionInfo.put(JSSEHelper.CONNECTION_INFO_REMOTE_PORT, "443");
return new SSLSocketFactory(JSSEHelper.getInstance().getSSLSocketFactory(alias, connectionInfo, null),
SSLSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
}
I am developing a mobile application with IBM Worklight and I have some issues with the authentication. I am using a custom authenticator and a custom login module for validating the user credentials against a Tivoli directory server.
This is the code I am using, it works when I run it like a java application (class with a main method) in Worklight Studio, but when I run it like a Worklight application (in the login function of my custom login module) it returns a naming exception and prints jndi.20
public boolean login(Map<String, Object> authenticationData) {
logger.info("SmaciLoginModule :: login");
try{
USERNAME = (String) authenticationData.get("username");
PASSWORD = (String) authenticationData.get("password");
String solicuser="uid="+USERNAME+",cn=users,dc=smaci,dc=ibm";
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://127.0.0.1:1389/");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, solicuser);
env.put(Context.SECURITY_CREDENTIALS, PASSWORD);
DirContext ctx = new InitialDirContext(env);
boolean result = ctx != null;
if(ctx != null)
ctx.close();
return result;
}catch (Exception e) {
throw new RuntimeException("Invalid credentials"+e.getMessage());
}
}
I hope that you can help me with my problem. I don't have experience working with LDAP, I appreciate any suggestion.
Thank you!
Are you trying to get the password from the user, with this line?
String pass=(String) entry.get("password").get().toString();
If so, that is unlikely to work. Passwords are almost never retrievable via LDAP. (The exceptions are slightly complex, so consider it impossible).
What you want to do instead is try to bind with the solicuser built DN, and the PASSWORD value. Then on success (and password is not empty, since that always succeeds, but as an anonymous bind, so you have to watch for it) you know you authenticated. Else you fail it. You might wish to examine the possible error messages. Various LDAP servers give different errors. Some will report a bad password, or a bad DN (i.e. No such user). Others not so much.
I want to explore openLDAP.. Can any one suggest me some websites for simple ldap codes?
There are multiple options if you are looking for java libraries
JNDI
JLDAP
Examples using jldap
If you want to explore what is LDAP.You can go for 389 Directory Server(Open LDAP )
Refer below link.Install it.It has GUI for administration.
http://directory.fedoraproject.org/wiki/Main_Page
For JNDI ,to call you can refer below site and code below to connect LDAP server
http://docs.oracle.com/javase/jndi/tutorial/ldap/models/operations.html
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, providerUrl);
env.put(Context.SECURITY_PRINCIPAL, UserContextBean.getEntrydn());
env.put(Context.SECURITY_CREDENTIALS, password);
env.put(Context.SECURITY_AUTHENTICATION, authenticationType);
LDAPContext ctx = new InitialLdapContext(env, null);
This ctx can be use to access directory.
I've run into a problem attempting to authenticate from within my web services. Here is the code that fails.
private InitialDirContext callDirectory(String password,
String usernameWithoutDomain) throws NamingException
{
InitialDirContext ctx;
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, _ldapUrl );
env.put(Context.SECURITY_AUTHENTICATION, "DIGEST-MD5");
env.put(Context.SECURITY_PRINCIPAL, usernameWithoutDomain );
env.put(Context.SECURITY_CREDENTIALS, password);
ctx = new InitialDirContext(env);
return ctx;
}
This code works against Active Directory on AIX using IBM's 1.5 JVM, but not on the same machine with the same VM when run inside WebSphere 6.1.
I've tried to control for all variables, and so far it looks like WebSphere is preventing the DIGEST-MD5 LDAP Authentication. Any ideas why?
Here is the stack trace:
javax.naming.AuthenticationNotSupportedException: DIGEST-MD5
at com.sun.jndi.ldap.sasl.LdapSasl.saslBind(LdapSasl.java:115)
at com.sun.jndi.ldap.LdapClient.authenticate(LdapClient.java:229)
at com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2652)
at com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:298)
at com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:190)
at com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:208)
at com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:151)
at com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:81)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:679)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:259)
at javax.naming.InitialContext.init(InitialContext.java:235)
at javax.naming.InitialContext.<init>(InitialContext.java:209)
at security.ActiveDirectoryReader.openDirectoryContext(ActiveDirectoryReader.java:80)
So that others can benefit from this:
modify the file :/opt/IBM/WebSphere/AppServer/java/jre/lib/security/java.security
do a search for security.provider and add a line at the bottom of the other providers (if it's not already in there):
security.provider.X=com.ibm.security.sasl.IBMSASL (where X is the next number in sequence for the lines above it)
We had this same issue, even opened a PMR with IBM (who still doesn't know how to fix)
The answer actually came from their own link:
http://www.ibm.com/developerworks/java/jdk/security/50/secguides/saslDocs/ibm.sasl.provider.guide.html
seems this is supposed to be "on" by default...