in Coding, Java, StackOverflow

A Windows SSO (for Java on client and server)

A couple of months ago I worked on a single sign-on (SSO) for a Windows client and server made in Java. The scenario was the following:

  • A client made with Java running on Windows
  • A server made with Java running on Windows
  • Both where logged-in to the same domain (an Active Directory LDAP)

The question was, how the server could get the identity (the name of the Windows account) of the client and – of course – how it could trust this information. But if the client would just send a name (e.g. from Java’s System.getProperty(""); method), the client could send anything.

The solution for this dilemma (trust what the client sends to you) is to use a (so called) trusted third party. A trusted third party is an instance which both, client and server, know and trust. The client authenticates itself to this party and the server can verify requests against it. In the scenario above, the domain of the company (an Active Directory LDAP) is the trusted third party. Each client identifies itself against this domain when it logs-in to Windows. Its Windows username and password are checked by the domain/LDAP. On the other side, the server has also access to the domain controller and can verify information send by the client.

The nice thing about this is, that the Windows domain is already configured on nearly every machine which stands in a company. Every company, bigger than maybe five people, will have a Windows domain to log-in. Therefor, a SSO based on the Windows domain will work right out of the box in most cases and we don’t need and configuration in our Java code, since it is already configured in Windows.

Java Native Access (JNA)

To use Windows and the domain controller for authentication, we can use native Windows APIs. To call those APIs in Java, we can use the Java Native Access (JNA) library, which you can find on GitHub at and on Maven central:

For example, to get all user groups of the current user, you would do:


On top of JNA exists a library called Waffle which encapsulates all functionality you need to implement user authentication. You can find it on GitHub at and also on Maven central:

You can use Waffle to create a token on the client, send it to the server (e.g. over HTTP or whatever) and to validate that token on the server. At the end of this process (create, send and validate) you will know on the server who the client is – for sure!

Here is an example of how to identify a client on the server. Note that this piece of code is executed completely on one machine. However, you could easily split it into two parts, one on the client and one on the server. The only thing you would need to do, is to exchange the byte[] tokens between client and server. I commented the appropriate lines of code.

(By the way, I asked this myself on Stackoverflow some times ago).

The only thing that is a little bit complicated with that solution is, that you need to do a small handshake between client and server. The client will send a token to the server, which will response with another token, which the client needs to answer again to get the final “you are authenticated” token from the server. To do this, you need to hold some state on the server for the duration of the handshake. Since the handshake is done in a second or two, I just used a limited cache from Google’s Guava library to hold maybe 100 client contexts on the server.

The exchanged tokens are validated against the underlying Windows and its domain.

Best regards,

  • Gusti Arya

    Hi, could you help me, i trying to get current client windows username, i add below code


    but then i get this error.

    com.sun.jna.platform.win32.Win32Exception: The security context does not allow impersonation of the client

    pls help

  • Hi Gusti Arya! You get the identity of the client from the ServerContext as shown in the example above. You will have the Windows user name in this object.

    Best regards, Thomas.

  • Mike Azazel

    im doing a jsf webapp and this is bringing me the user the server app runs on the server, not client… any ideas?

    • This approach will only work with a Java client (and server), not with a web application. As far as I know, there is no way to use Windows authentication
      in the browser to login on a website. If you are looking for a web SSO, you must go with something like OAuth or SAML.

      • Mike Azazel

        nah i got it to work with waffle
        user gets logged on at startpage, automatically
        i cast a httprequest element on my bean that gives me to logged on user

        • David K.

          I have the same problem, could you give me a brief explanaition how you did this?

        • vignesh kumar

          hi mike,

          am also trying same process .in server side ,i need to get the client user name ,whose accessing my server application,am facing so many issue ,could you please help me to resolve the issue ,Could you please post the code which you used to get the’s highly appreciate.

          • Mike Azazel

            hi vignesh,

            this is the relevant code from the login method in my session bean:

            // get logged in users name from http request
            HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
            String username = request.getUserPrincipal().getName();
            // extract the login name from the string received in the http servlet request
            username = username.substring(username.indexOf(“\”) + 1, username.indexOf(“\”) + 4);

            please note that this login method is annotated with postconstruct.

            then, in my web.xml, i have the following:




            i hope that this helps you.

          • vignesh kumar

            HI mike,

            Could you please tell, which waffle configuration you have been used .because so many configuration is there. like waffle-jna,waffle-jetty,waffle-tomcat 6,7,8,9 ,waffle-distro some more configuration also is there.

          • Mike Azazel

            hi vignesh
            what parts you need is defined by where your webapp runs on and if you use spring in your application and so on

            here are the dependencys that i needed to run it inside a tomcat8 with spring




            as for the token, you wouldnt need one working with this approach, at least i dont have any, the login method is all you need to get the username

            waffle is supposed to handle all this token stuff itself, i never had to do anything, when accessing the page i get a message from waffle st like ‘user xy has been logged in’

          • vignesh kumar

            HI mike ,

            Am using struts web application with tomcat 7. which dependency has been used in your application everything am using as jar file. because in struts we can not use dependency like spring. token is coming null,it’s not generating by default ,i have generated byte array token manually. but it’s getting failed in SecurityContext class .it’s returing value as “o”

          • vignesh kumar

            Hi mike ,

            Am trying above method in spring 3.0 and tomcat 6 ,am getting error in log “The token supplied to the function is invalid” .the token is start with TlRMTVNTUAACAAAADAA, Any idea. i have one more doubt ,while running application ,am getting authentication required window ,which username and password ,i have to give ,whether tomcat username/password or windows username/password. i have tried both ,am getting error as invalid token, kindly help me.this.

          • Mike Azazel

            Hi vignesh,

            the code posted above shows how i implemented it. its been in a productive environment for about half a year and works flawlessly.

            i havent wored with struts before, i guess you kinda have to figure that part out yourself.

          • vignesh kumar

            Hi mike ,
            Ya sure mike ,Now am working on spring based application ,i will figure it out .thank you

          • Mike Azazel

            you should be able to use my code as a drop in solution when working on a spring application
            let me know if you got it to work

          • vignesh kumar

            com.sun.jna.platform.win32.Win32Exception: The token supplied to the function is invalid am getting this exception ,i have generated the Token as a byte array

          • Santiago Barandiaran

            Hi Mike, I´m trying to do the same as you and been stuck for a few days..
            Now I´m trying with Waffle which seems to be very easy for getting the logged in Windows user of the user who´s making the request to my webApp but I´m receiving “NT AUTHORITYANONYMOUS LOGON” as principal.
            As I can see, you are requesting the principal from this request Object:


            What´s the dependency of this “FacesContext” because I imported these two:

            compile “com.sun.faces:jsf-api:2.2.9”
            compile “com.sun.faces:jsf-impl:2.2.9”

            but I´m getting NullPointerException on FacesContext.getCurrentInstance().

            Please, any help would be REALLY appreciatted.
            Thank you very much.

            Best regards.


          • Mike Azazel

            Hi Santiago,

            its javax.faces.context.FacesContext and it resides inside jsf-api (in my case 2.2.13)

            those are my jsf dependencies:



            I hope this information is helpful to you.

      • Armand Welsh

        On the server, you can use SPNEGO filter, to wrap any component of your website inside a Kerberos authenticated session. If you provide a mechanism to prompt for username/password, then you can even fallback to ntlm if the Kerberos authentication fails. Then IE, Chrome, and Firefox all will pass you credentials (transparently) to the server, provided the browser has trusted authentications enabled, and the server is in the local security policy for the browser.