WAFFLE: Windows Authentication in Java

23
Daniel Doubrovkine | @dblockdotorg

description

Windows Authentication for Java with WAFFLE presented at the NYCJavaSIG in February 2012.

Transcript of WAFFLE: Windows Authentication in Java

Page 1: WAFFLE: Windows Authentication in Java

Daniel Doubrovkine | @dblockdotorg

Page 2: WAFFLE: Windows Authentication in Java

“Most enterprise customers can’t login to your product.”

“What do you mean by you don’t support nested groups?”

Page 3: WAFFLE: Windows Authentication in Java

What is my canonical username?

What local groups am I a member of?

What domain groups am I a member of?

Page 4: WAFFLE: Windows Authentication in Java

User and Group Names Used Instead of SIDs

Used Net* Functions to Enumerate Local Groups

Tried to Use LDAP to Enumerate Domain Groups

Failed to Support Nested Groups

Failed to Resolve Domain Trusts … and much more that few people know about AD

Page 5: WAFFLE: Windows Authentication in Java

Enterprises are Switching to Smart Cards + PIN

Page 6: WAFFLE: Windows Authentication in Java

100% Java JNA http://github.com/twall/jna

Win32 API Won’t work on *nix

Page 7: WAFFLE: Windows Authentication in Java

BOOL LogonUser(

LPTSTR lpszUsername,

LPTSTR lpszDomain,

LPTSTR lpszPassword,

DWORD dwLogonType,

DWORD dwLogonProvider,

PHANDLE phToken );

advapi32.dll

Page 8: WAFFLE: Windows Authentication in Java

// a user handle

HANDLEByReference phUser = new HANDLEByReference();

Advapi32.INSTANCE.LogonUser(

"Administrator", "ENTERPRISE", "password",

WinBase.LOGON32_LOGON_NETWORK,

WinBase.LOGON32_PROVIDER_DEFAULT,

phUser);

Page 9: WAFFLE: Windows Authentication in Java

// user group memberships

WinNT.TOKEN_GROUPS groups = new WinNT.TOKEN_GROUPS(...);

Advapi32.INSTANCE.GetTokenInformation(

phUser,

WinNT.TOKEN_INFORMATION_CLASS.TokenGroups,

groups,

tokenInformationLength,

tokenInformationLength));

for (SID_AND_ATTRIBUTES sid : groups) {

}

Page 10: WAFFLE: Windows Authentication in Java

// current user name

Secur32.INSTANCE.GetUserNameEx(format, ...)

Advapi32.INSTANCE.ImpersonateLoggedOnUser(phUser);

// impersonated user

Secur32.INSTANCE.GetUserNameEx(format, ...)

Advapi32.INSTANCE.RevertToSelf();

Page 11: WAFFLE: Windows Authentication in Java

Current User Security Identifier

Group Memberships (a list of SIDs)

Privileges

Current

Thread

Current

Process

Page 12: WAFFLE: Windows Authentication in Java

HANDLE h =

Kernel32.INSTANCE.GetCurrentThread();

HANDLEByReference phToken = new

HANDLEByReference();

Advapi32.INSTANCE.OpenThreadToken(

h,

WinNT.TOKEN_DUPLICATE |

WinNT.TOKEN_QUERY,

true, phToken)

… enumerate groups with

Advapi32.INSTANCE.GetTokenInformation

Page 13: WAFFLE: Windows Authentication in Java

Since Windows 2000

Multi-Master Directory Service w/ Trusts

Storage

Domain Data

User Data

User Group Data

Security Data

Etc.

Active Directory Service Interface (ADSI)

Page 14: WAFFLE: Windows Authentication in Java

SSP = Security Support Provider Kerberos, Microsoft Windows NT LAN

Manager (NTLM), Negotiate

SSPI

Proprietary Implementation of GSSAPI (IETF Standard)

Integrated Distributed Security Services

Page 15: WAFFLE: Windows Authentication in Java

1. Insert a Smart Card into a Reader

2. Logon to a Server Joined to an AD Domain

3. Navigate to a Website, No Prompts

4. Check Permissions w/ Application

5. Logged on as a Domain User on the Server

6. $$$

Page 16: WAFFLE: Windows Authentication in Java

AcquireCredentialsHandle

InitializeSecurityContext

AcceptSecurityContext

Secur32.dll

Page 17: WAFFLE: Windows Authentication in Java
Page 18: WAFFLE: Windows Authentication in Java
Page 19: WAFFLE: Windows Authentication in Java

Waffle Provides Windows Authentication and Authorization Functions

Filters and Providers for Application Servers Tomcat, Jetty, WebSphere, etc.

Open-Source

http://waffle.codeplex.com

Page 20: WAFFLE: Windows Authentication in Java

Waffle-jna.jar + jna.jar + platform.jar

WEB-INF\web.xml <filter>

<filter-name>SecurityFilter</filter-name>

<filter-

class>waffle.servlet.NegotiateSecurityFilter</filter-

class>

</filter>

<filter-mapping>

<filter-name>SecurityFilter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

JSP Page

<%= request.getUserPrincipal().getName() %>

Page 21: WAFFLE: Windows Authentication in Java

GET /secure HTTP/1.1

HTTP/1.1 401 Unauthorized

WWW-Authenticate: Negotiate

WWW-Authenticate: NTLM

GET /secure HTTP/1.1

Authorization: Negotiate

YIGeBgYrBgEFBQKggZMwgZCgGjAYBgo…9kqa6BepAo=

HTTP/1.1 401 Unauthorized

WWW-Authenticate: Negotiate

oRUwE6ADCgEDoQwGCisGAQQBgjcCAgo=

GET /secure HTTP/1.1

Authorization: Negotiate

oUMwQaADCgEBojoEOE5UTE1TU1AAAQAAA…HQAAAA9SRy02

NDEwSU5URVJORVdT

HTTP/1.1 200 OK

WWW-Authenticate: Negotiate

oRswGaADCgEAoxIEEAEAAAB7J3i2ZZ/tlgAAAAA=

Page 22: WAFFLE: Windows Authentication in Java

IWindowsAuthProvider

IWindowsAccount

IWindowsComputer

IWindowsDomain

IWindowsIdentity

IntPtr securityToken = Advapi32.LogonUser(

username, domain, password);

WindowsIdentity windowsIdentity =

new WindowsIdentity(securityToken);

return windowsIdentity.groups;