Jinterop impersonation - java

I use the Jinterop library for an access to remote WMI.
JISystem.setAutoRegisteration(true);
JISession session = JISession.createSession(System.getenv("USERDOMAIN"), login, password);
session.useSessionSecurity(true);
final JIComServer server = new JIComServer(JIProgId.valueOf(WBEM_PROGID), HOST, session);
I want to use impersonation for accessing with current user and password to remote machine. But when I use empty login and password, I always get exception
jcifs.smb.SmbAuthException: Logon failure: unknown user name or bad password.
at jcifs.smb.SmbTransport.checkStatus(SmbTransport.java:546)
Is this possible to use impersonation in Jinterop?

I am not 100% sure, but I have worked with j-interop for some time and I have never seen or read about this feature, so I don't think that this is possible. In my opinion you always have to specify the credentials.
Further, I am curious if this is really working for you?:
JISystem.setAutoRegisteration(true);
This means that j-interop will automatically try to modify values/keys in the registry as needed. In my experience, in case you want to access the WbemScripting.SWbemLocator class, due to tighter security constraints (the necessary keys are owned by the 'TrustedInstaller' user) this automatic modification is not possible any more starting from Windows Vista and above. I always had to set this to false and modify the values/keys manually in the registry.

Related

LDAP bind authentication with Jetty

I am trying to secure Confluent Control Center 7.2.2 with the jetty LdapLoginModule. I have the following jaas configuration working.
c3 {
org.eclipse.jetty.jaas.spi.LdapLoginModule required
useLdaps="true"
contextFactory="com.sun.jndi.ldap.LdapCtxFactory"
hostname="ldaps.xxxx.xxxxx"
port="xxx"
bindDn=<user principal name>
bindPassword=<user password>
authenticationMethod="simple"
forceBindingLogin="true"
userBaseDn="DC=xxxx,DC=xxxx,DC=xxx,DC=xx"
userRdnAttribute="userPrincipalName"
userIdAttribute="userPrincipalName"
userObjectClass="user"
roleBaseDn="OU=xxxxxx,OU=xxx,OU=xxxxx,DC=xxxx,DC=xxxx,DC=xxx,DC=xx"
roleNameAttribute="cn"
roleMemberAttribute="member"
roleObjectClass="group";
};
I would like to avoid passing a bindDn and bindPassword and use the authenticating user credentials to bind instead. My understanding is that forceBindingLogin set to true should make that possible.
forceBindingLogin
Indicate whether to bind as the user that is authenticating (true), otherwise bind as the manager and perform a search to verify user password (false).
Although when I remove bindDn and bindPassword from my config I get the following error:
DAP: error code 1 - 000004DC: LdapErr: DSID-0C090A71, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, v3839
It looks like bindDn is still used when forceBindingLogin is set to true.
I noticed that in the Confluence documentation, the bindDn config went from optional to required between 6.1.9 and 6.2.0. Jetty was upgraded to 9.4.39, but there is no mention as to why bindDn would now be required.
I don't have experience with Confluent Control Center, but have been dealing with a lot of Java applications and OAuth that uses LDAP authentication during the years. As a DevOps I had to also manage a few LDAP instances myself so I will be rather speaking from that background.
The authentication process with OpenLDAP requires one of the following to be true:
Allows anonymous (connection) binding
This configuration allows you to connect to the LDAP server as an anonymous user and lookup any object in the tree and therefore find any groups, users, etc.
Manager/User dn (connection) binding
This configuration mandates you to connect to the LDAP server as a pre-configured user that has access to lookup objects in the tree and find the requested groups,users,etc. You can have many Manager DNs configured to access different parts of the LDAP tree.
Notice I mentioned CONNECTION binding - think of this as how you would connect to Postgres or MySQL. You need to have some credentials in order to lookup tables or if anonymous is enabled you can do pretty much anything.
The same thing applies to LDAP servers -- anonymous binding will allow you to establish a connection and lookup anything and manager / user dn requires authentication before the connection can be established.
People are not always deeply aware of LDAP's architecture and the documentation doesn't really help there. As such, the terminology makes you jump to the rational conclusion you jumped to:
#alex: I would like to avoid passing a bindDn and bindPassword and use the authenticating user credentials to bind instead
This would work only when the LDAP server is configured to allow Anonymous connections. If it is configured to require Manager/User DN connection:
When you bind as the user the authentication will likely pass (unless LDAP is configured not to allow that at all).
Once it succeeds it you would attempt to lookup the authorization objects (roles / groups / etc). At this point it will fail due to the inability to do the needed lookups and finally the result will be failed login.
To validate if this is the case you are ending in you should:
Use some tool to the LDAP server (you can try Apache Directory Studio
Setup a connection with binds as the bespoken user (i.e. my-username; not the manager dn, not a read-only dn)
Once you are connected try to lookup the userBaseDn and roleBaseDn DN's -- you are most likely not going to see any of the roles.
If the above is true then what you want is not possible with the current LDAP server setup.
If not -- then the LDAP server truly allows you to bind as the user and to lookup the directory tree. In this case you should open up a bug report with Confluent.

Java-Spring-LDAP-Kerberos

I need some help delegating user authentication in my spring-based application to Active Directory that seems to be delegating this responsibility to Kerberos - I can't seem to figure out how to do this. Here is more of what the mess really looks like:
I followed Spring guide on configuring Spring Security to work with an LDAP server. It went fine.
I got host, port of my actual LDAP server. I configure Spring Security to talk to it, it won't allow me to authenticate.
OK, I download jxplorer and connect to my LDAP server with it successfully. If jxplorer can connect to LDAP only knowing HOST, PORT, USERNAME, and PASSWORD, I figure my application should be able to do the same.
Weirdly, my LDAP does not show an OU=people. My people are scattered deeper in the tree among various OUs, an OU per department kind of way - but, most people are found equally deep inside the tree.
Also WEIRDLY, my actual people nodes that uniquely identify a person have no userPassword attribute.
For experimentation, I configure Spring Security in such a way that it tries to authenticate an individual by looking in the OU that represents my department and tell it to use as password mailNickname (using PlaintTextPasswordEncoder()) and it works fine - only on port 3268, not on 389.
At this point I start speculating - LDAP, is telling my spring-based app that it needs to talk to Kerberos, and I did not tell it how to do that, so that explains why my app fails to authenticate. BUT, no one told jxplorer that Kerberos will authenticate it and yet it managed to get a view of the LDAP tree. Clearly, my spring-app's assumptions != jxplorer's assumptions. I give them the exact same info yet one manages to authenticate the other not. Anyone any idea?
EDIT:
ok, so, I still do not have this solved, but my error has changed and that is a mark of progress, I suppose.
I configured spring according to this: link
Now, when I try to log in, if I give a wrong password or username, I get the complaint that clearly indicates that password is given wrong. However, if I give the correct password, the complaint differs.
The end of stack trace includes:
Caused by: javax.security.auth.login.LoginException: Pre-authentication information was invalid (24)
But, the debug also indicates that the user is found in kerberos database because it says: "principal is username#correct_realm" and "Added server's keyKerberos Principal correct_user#correct_realm" and does some hex dump.
Because of that, I am sure that my keytab is not doing its job. I am certain that my key tab is found by Spring because it says: KeyTab is my_keytab_file (otherwise it'd say: KeyTab is null).
If it is configured with Kerberos, you can try SPNEGO. It's one of the best libraries around for Kerberos in Java.
READ: http://spnego.sourceforge.net/
Sample code for Kerberos Auth:
Example usage (username/password):
public static void main(final String[] args) throws Exception {
System.setProperty("java.security.krb5.conf", "krb5.conf");
System.setProperty("sun.security.krb5.debug", "true");
System.setProperty("java.security.auth.login.config", "login.conf");
SpnegoHttpURLConnection spnego = null;
try {
spnego = new SpnegoHttpURLConnection("spnego-client", "dfelix", "myp#s5");
spnego.connect(new URL("http://medusa:8080/index.jsp"));
System.out.println(spnego.getResponseCode());
} finally {
if (null != spnego) {
spnego.disconnect();
}
}
}

How to create session in domino agent with functional id

I have some functional id to mailbox.
I need to connect to this mailbox via domino agent.(So I need to create session with functional id rights)
But when I'm trying to create session object with NotesFactory.createSession("", username, password); I have an exception:
Cannot create a session from an agent
So if anybody know how can I do it I'll be appriciate.
Advices that you need to configure certificates between two servers won't help me.
You cannot change the identity of a Java agent that way. An agent can only use
NotesFactory.createSession(); // no arguments
If it is a web agent that runs in response to a URL (either as a webqueryopen or webquerysave agent, or through the ?OpenAgent URL command), and you set Run as Web User in the agent properties, then the session will be created using the identity of the authenticated web user.
As for the DIIOP case, it sounds like your server is not configured properly for IIOP access. Check out this IBM Technote that describes the settings. (Pay no attention to the references to WebSphere in the TechNote. The problem would affect any IIOP client. The solution is to fix the server settings.)

Websphere MQ 7.5: User ID Access

I've installed the Websphere MQ 7.5 and written a Java-client to connect to the queue. To perform the task, I'ev created a custom connect-to-server channel that is based on the SYSTEM.DEF.SVRCONN channel.
Firstly, to block all users with administrator privileges and all anauthorized users for all channels I've types such a command (runmqsc TEST_MANAGER): SET CHLAUTH(*) TYPE(BLOCKUSER) USERLIST('nobody', *MQADMIN) . Now I see this restriction in the MQ Explorer (TEST_MANAGER -> Channels -> Channel Identification Records).
After that, to provide my test user (Java-client) with an access, I've typed such a command:
SET CHLAUTH(TEST_CHANNEL) TYPE(ADDRESSMAP) ADDRESS('*') MCAUSER('TestUser') .
Lastly, I've set the username/password pair in the Spring's UserCredentialsConnectionFactoryAdapter where the username is TestUser.
The problem is I can't connect with the 2035 MQRC_NOT_AUTHORIZED exception. If I remove the 'nobody'/*MQADMIN blocking rule, everything works fine (only the rule for the TestUser client rule presents).
SET CHLAUTH(TEST_CHANNEL) TYPE(ADDRESSMAP) ADDRESS('*')
MCAUSER('TestUser')
I do not think you understand this command. This command says that ALL applications connecting on channel 'TEST_CHANNEL' will use UserID of 'TestUser'.
I've set the username/password pair in the Spring's
UserCredentialsConnectionFactoryAdapter where the username is
TestUser.
Setting a Password is pointless, as MQ does NOT perform authentication. You need to purchase a 3rd party product (i.e. MQAUSX) to handle the authentication. Also, your CHLAUTH command is actually overriding whatever UserID you set in your Spring application.
The problem is I can't connect with the 2035 MQRC_NOT_AUTHORIZED exception. If I remove the 'nobody'/*MQADMIN blocking rule, everything works fine (only the rule for the TestUser client rule presents).
Did you use the setmqaut command to give the UserID 'TestUser' the appropriate access to the queue manager and queue?
Turn on the queue manager's Authority Event and to see exactly why MQ is returning 2035.

What parameters for an NTLM authentication can be automatized , and how to do it with java?

I want to know what parameters can be automatized out of the 6 used during an NTLM authentication, which are:
"Username" - The one used to login on the Operating System's profile currently in use. -Already automatized, using System.getProperty("user.name")
"Password" - Same as the above. -Probably can't be automated, but i'm never sure till i try and ask...
"ProxyAddress" - Address of the proxy, to which the authentication is "handshaked to" in order to pass. -I already pseudo-automatized, but its fixed code, thus bad.
"ProxyPort" - The listening port on the proxy previously explained. -I already pseudo-automatized, but its fixed code, thus bad.
"Workstation" - My PC's ID in the local network or something...I'm currently using my machine's property ID, and its working, but i have no idea if its the correct value, or if there is a need for a value in the first place. -No idea how to automatize, but i know it's possible. NEED HELP
"Domain" - No idea which domain it refers to, thus no idea what value it should have...leaving it blank seems to be working... -No idea how to automatize, but i know it's possible. NEED HELP
EXTRA INFO: I'm using the HtmlClient library for the process, including authentication.
DefaultCredentialsProvider credentialProvider = (DefaultCredentialsProvider) webClient.getCredentialsProvider();
credentialProvider.addNTLMCredentials(username, password, proxyAddress, proxyPort, workstation, domain);
webClient.setUseInsecureSSL(true);
I'm sort of assuming that you're talking about Apache HTTPClient and HTLMUnit, but I'm basing that assumption off the method signatures in the code you provided, so I apologize if I'm mistaken.
For NTLM, this is the remote username, not necessarily the currently logged in user on the local host. I suspect that these are the same user in your scenario, but I did want to point that out. In that case, yes, using the user.name system property will provide the name of the currently logged in user:
System.getProperty("user.name");
on Windows, you can also use the USERNAME environment variable:
System.getEnv("USERNAME");
or you could use the com.sun.security.auth.module.NTSystem class:
new NTSystem.getName();
You cannot get the user's password. However, you may still be able to perform single signon where the user does not need to provide a password (more on that below.)
The Java mechanism for specifying HTTP proxies is using the http.proxyHost system property:
String proxyHost = System.getProperty("http.proxyHost");
Note that you should also check the http.nonProxyHosts system property.
Some JREs (Mac OS comes to mind immediately) will set these system properties based on the system proxy settings. If this is not set by your JRE, you will probably want to try to determine the proxy from another source. On Unix systems, you may wish to use the HTTP_PROXY environment variable. On Windows systems, you're likely best off using the ProxySelector class, as explained in this stackoverflow post.
Similar to the http.proxyHost system property, the Java mechanism is with the http.proxyPort system property:
int proxyPort = Integer.parseInt(System.getProperty("http.proxyPort"));
To reliably get your hostname on Unix, you should really call gethostname(2) via JNI or exec /usr/bin/hostname, unfortunately. On Windows, you may use the COMPUTERNAME environment variable:
System.getEnv("COMPUTERNAME");
You can get the domain name that the local machine is joined to, however (short of prompting the user), there's no way to automatically get the domain name of the machine you're authenticating to. Of course this is moot if your local workstation and the authentication target are on the same domain. Thus, on Windows, you can either use the USERDOMAIN environment variable:
System.getEnv("USERDOMAIN");
or you can use the NTSystem class:
new NTSystem().getDomain();
Whew.
As for implementing "single signon" (such that the user need not provide a password):
You may be able to perform single signon (without needing a password) by using the Java Kerberos functionality, however I was unsuccessful in this because Java requires explicit Kerberos configuration (and does not use the host's configuration) and it does not implement some ciphers required by Active Directory. (Or that's my understanding.)
You could also perform single signon with NTLM or SPNEGO (Kerberos) by using JNI to call InitializeSecurityContext and pass the resulting tokens in the WWW-Authenticate header.

Categories

Resources