I'm aware I can call out to Active Directory and do queries provided I have a cleartext username and password. (I don't want to do that)
In VB, I can set authorisation levels by NT group - and the user doesn't have to enter their password nor, store it in a text file. (My understanding is that this has access to the Windows AD ticket).
I also know I can shell out to the command line and parse the output - to get the users groups - this is problematic.
How can I replicate getting the executing user's NT groups without a password in Java?
(It is beginning to sound like I'll have to call the Win32 API with JNA to get the kerberos ticket - I'm hoping there is a simpler way.)
You should split up your question in two because you're mixing authentication with authorization. Kerberos works very pleasently with Java on Windows with some caveats due to MS. Having said that use the Kerberos ticket with the provided principal to authenticate against AD and retrieve the user's memberOf values to see in which groups the user is in.
Related
i've connected successfull to Azure Active Directory trough LDAP protocol with JAVA, i'm able to get users and their attributes.
I'm trying to change users's password but everytime i try to do it i receive this error from LDAP: "error code 50 - 00000005: SecErr: DSID-031A1256, problem 4003 (INSUFF_ACCESS_RIGHTS), data 0"
I've checked that the user and credential used for password reset have Administrative right (Global Administrator on Azure).
I've noticed that same problems appears when using LDAP GUI client: it's not possible to change user password because of insufficient right.
I'm struggling on how to do it but i've tried quite all things...
Have you got any suggestions?
Thank You
I need to store windows username and credentials to later run some process that requires these credentials.
When I am collecting these as inputs from user, I want to validate whether credentials are correct or not. Is there a native api in Java that can help me validate windows system credentials?
I was going through LoginContext class but looks like it can only be used for SSO purpose.
One other suggestion I received was to try and start a process which requires these credentials and see if it works or fails. But this does not look the proper approach.
Please let me know if anyone has done this before or have any idea how to get it done.
Thanks,
Piyush
By credentials, you mean the user's actual password? Then you can use LDAP to try to connect to a Windows Active Directory. See related question: Windows password Authentication with LDAP
A more elaborate way to do this is to use native windows calls, perhaps via the JNA platform: http://jna.java.net/javadoc/platform/com/sun/jna/platform/win32/package-summary.html
There's a project called 'waffle' that wrapped this in a more usefull library, see e.g. the logonUser function in https://github.com/dblock/waffle/blob/master/Source/JNA/waffle-jna/src/waffle/windows/auth/impl/WindowsAuthProviderImpl.java. This talks straight to the win32 advapi32.dll.
This will also allow you to do windows authentication for local users, without a domain.
EDIT: Full working code from OP
import com.sun.jna.platform.win32.Advapi32;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.WinBase;
import com.sun.jna.platform.win32.WinNT.HANDLEByReference;
HANDLEByReference phUser = new HANDLEByReference()
if(! Advapi32.INSTANCE.LogonUser("administrator", InetAddress.getLocalHost().getHostName(),
"password", WinBase.LOGON32_LOGON_NETWORK, WinBase.LOGON32_PROVIDER_DEFAULT, phUser))
{
throw new LastErrorException(Kernel32.INSTANCE.GetLastError());
}
I have a (java) web-application, and i have enabled NTLM Authentication.
When the logon prompt is presented by the browser in our (windows) intranet environment.
The behavior i see is:
NTLM prompt does not seem to be doing any authentication at all, i am able to type any random string in userid prompt and it allows the user to proceed into the application. The prompt never fails the user.
So, what do i need to check at the server end to find if authentication succeeded or not?
The idea behind NTLM auth is that the logged on user can proceed with connection without explicitly entering his username and password again. So whatever your application asks you is irrelevant (as you can see it yourself) and instead your system credentials are used.
NTLM authentication has been broken for a number of years -- NTLM 2 shipped with NT 4, so hopefully people have moved on by now. If you want to use Active Directory login information, you should use Kerberos instead.
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.
Is it possible to use the credentials (or even a token, that a user entered when he logged in windows, lets say XP). what I am in search here is not applying a single sign on (which requires signing in again), but the single sign on would be that of the MS windows log-in window.
Is this possible? I understand security in windows is of high importance as well, but isn't there a way to get a token and use it in some other authentication mechanism?
Note: first and only sign in would be that of the Microsoft Windows Log in window and then the user would be able to access my application using the cached credentials (but without re loggin in).
You can do it if your machine is a member of domain. Google for GSSAPI. And use this string for your login module configuration:
com.sun.security.auth.module.Krb5LoginModule required debug=true useTicketCache=true doNotPrompt=true;
Note, this works only for Sun's JVM, as far as I know IBM JVMs do not support getting the ticket from OS.
Also, here is more information for you: http://msmvps.com/blogs/sp/archive/2007/06/05/integrating-java-jdbc-and-kerberos.aspx
Also, for this to work on modern version of Windows you have to tweak your registry settings:
On the Windows Server 2003 and Windows 2000 SP4, here is the required registry setting:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Kerberos\Parameters
Value Name: allowtgtsessionkey
Value Type: REG_DWORD
Value: 0x01
Here is the location of the registry setting on Windows XP SP2:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Kerberos\
Value Name: allowtgtsessionkey
Value Type: REG_DWORD
Value: 0x01