Waffle at NYCJavaSig

23
Daniel Doubrovkine | @dblockdotorg

description

Windows Authentication for Java with WAFFLE presented at NYJavaSig, February 2012

Transcript of Waffle at NYCJavaSig

Page 1: Waffle at NYCJavaSig

Daniel Doubrovkine | @dblockdotorg

Page 2: Waffle at NYCJavaSig

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

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

Page 3: Waffle at NYCJavaSig

What is my canonical username?What local groups am I a member of?What domain groups am I a member of?

Page 4: Waffle at NYCJavaSig

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 GroupsFailed to Resolve Domain Trusts

… and much more that few people know about AD

Page 5: Waffle at NYCJavaSig

Enterprises are Switching to Smart Cards + PIN

Page 6: Waffle at NYCJavaSig

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

Win32 APIWon’t work on *nix

Page 7: Waffle at NYCJavaSig

BOOL LogonUser( LPTSTR lpszUsername, LPTSTR lpszDomain, LPTSTR lpszPassword, DWORD dwLogonType, DWORD dwLogonProvider,

PHANDLE phToken );

advapi32.dll

Page 8: Waffle at NYCJavaSig

// 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 at NYCJavaSig

// 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 at NYCJavaSig

// current user name

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

Advapi32.INSTANCE.ImpersonateLoggedOnUser(phUser);

// impersonated user

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

Advapi32.INSTANCE.RevertToSelf();

Page 11: Waffle at NYCJavaSig

Current User Security IdentifierGroup Memberships (a list of SIDs)Privileges

Current Thread

Current Process

Page 12: Waffle at NYCJavaSig

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 at NYCJavaSig

Since Windows 2000Multi-Master Directory

Service w/ Trusts Storage Domain Data User Data User Group Data Security Data Etc.

Active Directory Service Interface (ADSI)

Page 14: Waffle at NYCJavaSig

SSP = Security Support Provider Kerberos, Microsoft Windows NT LAN

Manager (NTLM), Negotiate

SSPIProprietary Implementation of

GSSAPI (IETF Standard) Integrated Distributed Security

Services

Page 15: Waffle at NYCJavaSig

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 at NYCJavaSig

AcquireCredentialsHandleInitializeSecurityContextAcceptSecurityContext

Secur32.dll

Page 17: Waffle at NYCJavaSig
Page 18: Waffle at NYCJavaSig
Page 19: Waffle at NYCJavaSig

Waffle Provides Windows Authentication and Authorization Functions

Filters and Providers for Application ServersTomcat, Jetty, WebSphere, etc.

Open-Source

http://waffle.codeplex.com

Page 20: Waffle at NYCJavaSig

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 at NYCJavaSig

GET /secure HTTP/1.1

HTTP/1.1 401 UnauthorizedWWW-Authenticate: NegotiateWWW-Authenticate: NTLM

GET /secure HTTP/1.1Authorization: Negotiate YIGeBgYrBgEFBQKggZMwgZCgGjAYBgo…9kqa6BepAo=

HTTP/1.1 401 UnauthorizedWWW-Authenticate: Negotiate oRUwE6ADCgEDoQwGCisGAQQBgjcCAgo=

GET /secure HTTP/1.1Authorization: Negotiate oUMwQaADCgEBojoEOE5UTE1TU1AAAQAAA…HQAAAA9SRy02NDEwSU5URVJORVdT

HTTP/1.1 200 OKWWW-Authenticate: Negotiate oRswGaADCgEAoxIEEAEAAAB7J3i2ZZ/tlgAAAAA=

Page 22: Waffle at NYCJavaSig

IWindowsAuthProviderIWindowsAccountIWindowsComputerIWindowsDomainIWindowsIdentity

IntPtr securityToken = Advapi32.LogonUser( username, domain, password);

WindowsIdentity windowsIdentity = new WindowsIdentity(securityToken);

return windowsIdentity.groups;

Page 23: Waffle at NYCJavaSig