in Coding

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,

Write a Comment



  1. 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

  2. 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.

    • 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.

      • 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

        • 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.

          • 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.

          • 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.

          • 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’

          • 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”

          • 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.

          • 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.

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

          • 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

          • 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

          • 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.


          • 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.

          • Thank you for your response.
            I realized that I have to use that if it´s a jsf application, that´s not my case.
            The problem that I have is the following:

            I have a tomcat deployed on my PC, this server is on my Companies domain. When I make a request to the login page through my pc, I receive the principal name without the need of entering my credentials on the prompt… if I make a request from another computer, the prompt for entering the credentials appear.
            Do you know if it´s possible with Waffle to receive the Windows user without the need of entering the credentials??

            Thank you very much for your help, It´s been a week since I started with this and I don´t know how to continue.

          • hi santiago

            what ur experiencing is basic authentication. for single sign on (no prompts), waffle uses the ntlm protocol.

            you need to have a negotiatesecurityfilter, so ntlm is used if supported by browser, and basic authentication when its not.

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




            btw, in firefox u need to add the application server to
            ‘about:config’, ‘network.automatic-ntlm-auth.trusted-uris’

            hope that helps.

          • Thank you for your help Mike, That´s the only configuration you have to get it working??

            Did you have to create a servicePrincipalName, keytab, or something like that??

          • yeah, if you work with a jsf-webapp its all thats needed.

            appearently you dont use jsf, im afraid theres no way around tinkering around with it a bit^^ there might be some useful on that info in the main article above

            good luck

      • 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.

    • If HttpServletRequest.getRemoteUser() returns null, the user is not authenticated. Maybe the authentication didn’t work or you made a mistake in your Spring Security config?

  3. Hi, I have a web-application which uses the setup httpd (for SSL) + tomcat + spring-security + waffle for some time now. That does the sso part and also populates the active directory roles to which the user is assigned. I use these roles for authorization i.e. they are verified to decide if the logged-in user may use the web-application or not. The web-application is running at my customers location in an highly secured environment.

    I am now looking for ways to optimize this or better said to find if there is anything that can be optimized.

    Since the web-application is already running in a secured environment, a user would get to the httpd only if he or she is fully authenticated. Now that I use waffle, the authentication part gets repeated. Please correct me if I am wrong. In my web application i only need to know the logged-in users account and the AD roles that he/she is assigned to.

    Is there a way to access these information without needing to re-authentication?

    Is it possible to retrieve these user data at httpd level and inject them in the spring-security?

    Will use of ldap integrated in spring-security be more appropriate in my situation?

    • Hey Hrithick! First of all, sorry for my late answer. I totally forgot to answer you. So here’s what I think:

      > Is there a way to access these information without needing to re-authentication?

      I don’t think so. Even if you are in a “highly secured environment”, the client is still a client and you cannot trust it. Since most security attacks come from inside of an organisation, it makes no difference if you are in a secured environment. You still need to authenticate the client.

      > Is it possible to retrieve these user data at httpd level and inject them in the spring-security?

      I don’t know. I’m not familiar with httpd.

      > Will use of ldap integrated in spring-security be more appropriate in my situation?

      Even if you use LDAP within Spring, you still need a way to authenticate the user. I think that Spring Security can do an SSO such as Waffle. However, you could do the SSO with Waffle and then get additional user information via LDAP on the server. That might be more flexible.

  4. Hi,
    I have a Swing application, we will browse the application url, it will download the jnlp file. If click on the jnlp file, it will execute and prompt the swing application login screen.

    I needs to automatically login to the swing application using windows system credentials.
    Please guide me on this.


  • writeessay August 8, 2019

    I have a Swing application, we will browse the application url, it will download the jnlp file. If click on the jnlp file, it will execute and prompt the swing application login screen.

    I needs to automatically login to the swing application using windows system credentials.
    Please guide me on this.