waffle at nycjavasig
DESCRIPTION
Windows Authentication for Java with WAFFLE presented at NYJavaSig, February 2012TRANSCRIPT
Daniel Doubrovkine | @dblockdotorg
“Most enterprise customers can’t login to your product.”
“What do you mean by you don’t support nested groups?”
What is my canonical username?What local groups am I a member of?What domain groups am I a member of?
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
Enterprises are Switching to Smart Cards + PIN
100% Java JNA http://github.com/twall/jna
Win32 APIWon’t work on *nix
BOOL LogonUser( LPTSTR lpszUsername, LPTSTR lpszDomain, LPTSTR lpszPassword, DWORD dwLogonType, DWORD dwLogonProvider,
PHANDLE phToken );
advapi32.dll
// a user handle
HANDLEByReference phUser = new HANDLEByReference();
Advapi32.INSTANCE.LogonUser( "Administrator", "ENTERPRISE", "password",
WinBase.LOGON32_LOGON_NETWORK, WinBase.LOGON32_PROVIDER_DEFAULT, phUser);
// 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) {
}
// current user name
Secur32.INSTANCE.GetUserNameEx(format, ...)
Advapi32.INSTANCE.ImpersonateLoggedOnUser(phUser);
// impersonated user
Secur32.INSTANCE.GetUserNameEx(format, ...)
Advapi32.INSTANCE.RevertToSelf();
Current User Security IdentifierGroup Memberships (a list of SIDs)Privileges
Current Thread
Current Process
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
Since Windows 2000Multi-Master Directory
Service w/ Trusts Storage Domain Data User Data User Group Data Security Data Etc.
Active Directory Service Interface (ADSI)
SSP = Security Support Provider Kerberos, Microsoft Windows NT LAN
Manager (NTLM), Negotiate
SSPIProprietary Implementation of
GSSAPI (IETF Standard) Integrated Distributed Security
Services
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. $$$
AcquireCredentialsHandleInitializeSecurityContextAcceptSecurityContext
Secur32.dll
Waffle Provides Windows Authentication and Authorization Functions
Filters and Providers for Application ServersTomcat, Jetty, WebSphere, etc.
Open-Source
http://waffle.codeplex.com
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() %>
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=
IWindowsAuthProviderIWindowsAccountIWindowsComputerIWindowsDomainIWindowsIdentity
IntPtr securityToken = Advapi32.LogonUser( username, domain, password);
WindowsIdentity windowsIdentity = new WindowsIdentity(securityToken);
return windowsIdentity.groups;