waffle: windows authentication in java
DESCRIPTION
Windows Authentication for Java with WAFFLE presented at the NYCJavaSIG in February 2012.TRANSCRIPT
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 Groups
Failed to Resolve Domain Trusts … and much more that few people know about AD
Enterprises are Switching to Smart Cards + PIN
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 Identifier
Group 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 2000
Multi-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
SSPI
Proprietary 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. $$$
AcquireCredentialsHandle
InitializeSecurityContext
AcceptSecurityContext
Secur32.dll
Waffle Provides Windows Authentication and Authorization Functions
Filters and Providers for Application Servers Tomcat, 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 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=
IWindowsAuthProvider
IWindowsAccount
IWindowsComputer
IWindowsDomain
IWindowsIdentity
IntPtr securityToken = Advapi32.LogonUser(
username, domain, password);
WindowsIdentity windowsIdentity =
new WindowsIdentity(securityToken);
return windowsIdentity.groups;