Santiago Santiago - 21 days ago 5
Java Question

Get windows user logged in on WebApp (JAVA)

I´ve been stucked with this task for days now.. In the login form of my web application, before the user could enter the username and password, I want to receive in the request the username of his Windows account. After a lot of research I´ve found that Kerberos is what I have to use, but I don´t know how.
I have access to the Active Directory server, so I created the service principal name, established on Java the connection to the AD, but it´s impossible to me to get the windows user.

Now I´m trying yo use Waffle, and as I read, is as simple as import some JARs and in a JSP file get the principal name (it´s suppose to be the Windows user), but as I sayed, I couldn´t do it.

Has anyone done something similar before??

Any help would be REALLY appreciatted,

Thanks in advance.

UPDATE:

As you requested, this is what I´ve done so far:

On the WServer 2012 R2 (where I have the AD) I created a user called santi.mitrol.net

Register a spn to that user with the following command:

setspn -A HTTP/santi.mitrol.net santi.mitrol.net


and after this, I created the related keytab:

ktpass -out C:\temp\test.keytab -princ HTTP/santi.mitrol.net@DEV-MITROL.LOCAL -mapUser santi.mitrol.net -mapOp set -pass MYPASS -crypto RC4-HMAC-NT -pType KRB5_NT_PRINCIPAL


After this setup, I created this project: https://github.com/spring-projects/spring-security-kerberos/tree/master/spring-security-kerberos-samples/sec-server-win-auth/src/main but I can´t make it work...

With Waffle the same.. on my web.xml I have this:

<filter-name>SecurityFilter</filter-name>
<!--<filter-class>waffle.servlet.NegotiateSecurityFilter</filter-class>-->
<filter-class>net.mitrol.config.activedirectory.CustomFilter</filter-class>

<filter-name>SecurityFilter</filter-name>
<url-pattern>/*</url-pattern>


But when I make a request to the Tomcat that I have deployed on my PC from another PC, they get the prompt for entering the credentials, and that´s not what I need, I only need to receive on the request the Windows user that is logged in on the machine that is making the request.

Thanksssss

Answer

Ok, after two weeks, I could finally get it working!!!!

I´m going to post the whole process with as much detail as I can so no one suffers what I´ve suffered.

In this process I used three computers in the domian DEV-MITROL.LOCAL:

  • Domain Controller: hostname: AR-SRV-DC-007 user: Administrator pass: somePass40

  • Tomcat Machine: ip: 192.168.40.91 (I created a dns entry on the DC to resolve this IP to santi.dev-mitrol.net) user: tomcat pass: tomcatPass40

  • Client Machine to make the requests to the Tomcat Machine (It won´t work properly if you make the request from the same machine that you are running the server)

Steps:

1) Logged in on the DC with the Administrator user y created this SPN:

setspn -A HTTP/santi.dev-mitrol.net tomcat
setspn -A HTTP/santi.dev-mitrol.net.dev-mitrol.local tomcat

2) Locate the user "tomcat" on "Administrative Tools>Active Directory Users and Computers" and in the Delegation Tab select the option "Trust this user for delegation to any service (Kerberos only)" and in the "Account" tab, in "Account Options" check "Do not require Kerberos preauthenication".

3) Create the keytab whit this command:

ktpass -princ HTTP/santi.dev-mitrol.net.dev-mitrol.local@DEV-MITROL.LOCAL -mapuser tomcat@DEV-MITROL.LOCAL -pass * -ptype KRB5_NT_PRINCIPAL -out test.keytab

4) Now, time to log in with the tomcat user and paste the keytab created on this path:

C:\Program Files\Apache Software Foundation\Tomcat 8.5\conf\

Apart from this, you have to create two more files in this folder:

KRB5.ini

[libdefaults]
default_realm = DEV-MITROL.LOCAL
default_tkt_enctypes = rc4-hmac,aes256-cts-hmac-sha1-96,aes128-cts-hmac-sha1-96
default_tgs_enctypes = rc4-hmac,aes256-cts-hmac-sha1-96,aes128-cts-hmac-sha1-96
forwardable=true

[realms]
DEV-MITROL.LOCAL = {
kdc = AR-SRV-DC-007
}

[domain_realm]
dev-mitrol.local= DEV-MITROL.LOCAL
.dev-mitrol.local= DEV-MITROL.LOCAL

and JAAS.conf

com.sun.security.jgss.krb5.initiate {
com.sun.security.auth.module.Krb5LoginModule required;
};

com.sun.security.jgss.krb5.accept {
com.sun.security.auth.module.Krb5LoginModule required
storeKey=true
useKeyTab=true
keyTab="file:///C:/Program Files/Apache Software Foundation/Tomcat 8.5/conf/test.keytab"
principal="HTTP/desarrollo.mitrol.net.dev-mitrol.local";
};

5) Edit the web.xml file that is in the same folder, and include the SPNEGO Filter:

<filter>
    <filter-name>SpnegoHttpFilter</filter-name>
    <filter-class>net.sourceforge.spnego.SpnegoHttpFilter</filter-class>
    <init-param>
        <param-name>spnego.allow.basic</param-name>
        <param-value>true</param-value>
    </init-param>

    <init-param>
        <param-name>spnego.allow.localhost</param-name>
        <param-value>true</param-value>
    </init-param>

    <init-param>
        <param-name>spnego.allow.unsecure.basic</param-name>
        <param-value>true</param-value>
    </init-param>

    <init-param>
        <param-name>spnego.login.client.module</param-name>
        <param-value>com.sun.security.jgss.krb5.initiate</param-value>
    </init-param>

    <init-param>
        <param-name>spnego.krb5.conf</param-name>
        <param-value>krb5.ini</param-value>
    </init-param>

    <init-param>
        <param-name>spnego.login.conf</param-name>
        <param-value>jaas.conf</param-value>
    </init-param>

    <init-param>
        <param-name>spnego.login.server.module</param-name>
        <param-value>com.sun.security.jgss.krb5.accept</param-value>
    </init-param>

    <init-param>
        <param-name>spnego.prompt.ntlm</param-name>
        <param-value>true</param-value>
    </init-param>

    <init-param>
        <param-name>spnego.logger.level</param-name>
        <param-value>1</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>SpnegoHttpFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

6) Create a JSP file in "C:\Program Files\Apache Software Foundation\Tomcat 8.5\webapps\ROOT" with this content:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <title>Hello SPNEGO Example</title>
    </head>
    <body>
        Hello <%= request.getRemoteUser() %> !
    </body>
</html> 

7) If you have followed this steps, it should be working and you will be receiving on your request the name of the Windows user.

Hope it helps.