Waffle at NYCJavaSig


Published on

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

Published in: Technology
1 Like
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide
  • The local computer is the computer from which LogonUser was called (advapi32.dll).
  • The security context is the user account that the system uses to enforce security when a thread attempts to access a securable object.
  • On Windows, this works because of the  Security Support Provider Interface, aka SSPI . SSPI is a well-defined API for obtaining integrated security services for, among other things, authentication for any distributed application protocol. A client-server conversation is an example of such an application. SSPI is a Microsoft proprietary implementation of  GSSAPI , an IETF standard. Security Support Provider (SSP) A dynamic-link library (DLL) that implements the SSPI by making one or more security packages available to applications. Each security package provides mappings between an application's SSPI function calls and an actual security model's functions. Security packages support security protocols such as Kerberos authentication and the Microsoft LAN Manager (Windows NT Challenge/Response (NTLM)). Negotiate: A security support provider (SSP) that acts as an application layer between Security Support Provider Interface (SSPI) and the other SSPs. Negotiate analyzes the request and picks the best SSP to handle the request based on customer-configured security policy.
  • When a client wants to authenticate to a server, it needs to supply credentials and send them to the server. The server needs to validate this, reply that the credentials were kosher and possibly continue executing code on behalf of the client. Credentials can come in a variety of forms, such as a username and password or a notarized birth certificate from City Hall. Sending those to the server needs to be secure: you don’t want to send credentials to the wrong server, the server wants to make sure you’re really who you claim to be and nobody should be able to intercept this data on the wire and reuse it. The how part of this is the job of the authentication protocol, such as, for example, NTLM or Kerberos. Because there’re many protocols, SSPI exchanges so called  tokens , opaque blobs of data. the protocol can put anything in the blobs. Protocols often require several exchanges. For example, I may need to obtain the server’s public key, encrypt credentials, send them with my public key and receive an encrypted confirmation of success. Therefore both client and server maintain a so called  security context  during this conversation. SSPI allows you to do all this with any protocol or SSPI provider. There’s an NTLM SSPI provider, Kerberos SSPI provider, etc. SSPI describes three important calls that do all of the above.
  • Waffle at NYCJavaSig

    1. 1. Daniel Doubrovkine | @ dblockdotorg
    2. 2. <ul><li>“ Most enterprise customers can’t login to your product.” </li></ul><ul><li>“ What do you mean by you don’t support nested groups?” </li></ul>
    3. 3. <ul><li>What is my canonical username? </li></ul><ul><li>What local groups am I a member of? </li></ul><ul><li>What domain groups am I a member of? </li></ul>
    4. 4. <ul><li>User and Group Names Used Instead of SIDs </li></ul><ul><li>Used Net* Functions to Enumerate Local Groups </li></ul><ul><li>Tried to Use LDAP to Enumerate Domain Groups </li></ul><ul><li>Failed to Support Nested Groups </li></ul><ul><li>Failed to Resolve Domain Trusts </li></ul><ul><li>… and much more that few people know about AD </li></ul>
    5. 5. <ul><li>Enterprises are Switching to Smart Cards + PIN </li></ul>
    6. 6. <ul><li>100% Java </li></ul><ul><ul><li>JNA http://github.com/twall/jna </li></ul></ul><ul><li>Win32 API </li></ul><ul><ul><li>Won’t work on *nix </li></ul></ul>
    7. 7. <ul><ul><li>BOOL LogonUser( LPTSTR lpszUsername , LPTSTR lpszDomain , LPTSTR lpszPassword , DWORD dwLogonType , DWORD dwLogonProvider , PHANDLE phToken ); </li></ul></ul>advapi32.dll
    8. 8. <ul><li>// a user handle </li></ul><ul><li>HANDLEByReference phUser = new HANDLEByReference(); </li></ul><ul><li>Advapi32.INSTANCE.LogonUser( &quot;Administrator&quot;, &quot;ENTERPRISE&quot;, &quot;password&quot;, </li></ul><ul><li>WinBase.LOGON32_LOGON_NETWORK, WinBase.LOGON32_PROVIDER_DEFAULT, phUser ); </li></ul>
    9. 9. <ul><li>// user group memberships </li></ul><ul><li>WinNT.TOKEN_GROUPS groups = new WinNT.TOKEN_GROUPS(...); </li></ul><ul><li>Advapi32.INSTANCE.GetTokenInformation( phUser , </li></ul><ul><li>WinNT.TOKEN_INFORMATION_CLASS.TokenGroups, groups , tokenInformationLength, tokenInformationLength)); </li></ul><ul><li>for (SID_AND_ATTRIBUTES sid : groups ) { </li></ul><ul><li>} </li></ul>
    10. 10. <ul><ul><li>// current user name </li></ul></ul><ul><ul><li>Secur32.INSTANCE.GetUserNameEx(format, ...) </li></ul></ul><ul><ul><li>Advapi32.INSTANCE.ImpersonateLoggedOnUser(phUser); </li></ul></ul><ul><ul><li>// impersonated user </li></ul></ul><ul><ul><li>Secur32.INSTANCE.GetUserNameEx(format, ...) </li></ul></ul><ul><ul><li>Advapi32.INSTANCE.RevertToSelf(); </li></ul></ul>
    11. 11. <ul><li>Current User Security Identifier </li></ul><ul><li>Group Memberships (a list of SIDs) </li></ul><ul><li>Privileges </li></ul>Current Thread Current Process
    12. 12. <ul><li>HANDLE h = Kernel32. INSTANCE.GetCurrentThread(); </li></ul><ul><li>HANDLEByReference phToken = new HANDLEByReference(); </li></ul><ul><li>Advapi32. INSTANCE.OpenThreadToken( h , </li></ul><ul><li>WinNT. TOKEN_DUPLICATE | WinNT.TOKEN_QUERY, </li></ul><ul><li>true, phToken ) </li></ul><ul><li>… enumerate groups with Advapi32.INSTANCE.GetTokenInformation </li></ul>
    13. 13. <ul><li>Since Windows 2000 </li></ul><ul><li>Multi-Master Directory Service w/ Trusts </li></ul><ul><ul><ul><li>Storage </li></ul></ul></ul><ul><ul><ul><li>Domain Data </li></ul></ul></ul><ul><ul><ul><li>User Data </li></ul></ul></ul><ul><ul><ul><li>User Group Data </li></ul></ul></ul><ul><ul><ul><li>Security Data </li></ul></ul></ul><ul><ul><ul><li>Etc. </li></ul></ul></ul><ul><li>Active Directory Service Interface (ADSI) </li></ul>
    14. 14. <ul><li>SSP = Security Support Provider </li></ul><ul><ul><li>Kerberos, Microsoft Windows NT LAN Manager (NTLM), Negotiate </li></ul></ul><ul><li>SSPI </li></ul><ul><ul><li>Proprietary Implementation of GSSAPI (IETF Standard) </li></ul></ul><ul><ul><li>Integrated Distributed Security Services </li></ul></ul>
    15. 15. <ul><li>Insert a Smart Card into a Reader </li></ul><ul><li>Logon to a Server Joined to an AD Domain </li></ul><ul><li>Navigate to a Website, No Prompts </li></ul><ul><li>Check Permissions w/ Application </li></ul><ul><li>Logged on as a Domain User on the Server </li></ul><ul><li>$$$ </li></ul>
    16. 16. <ul><li>AcquireCredentialsHandle </li></ul><ul><li>InitializeSecurityContext </li></ul><ul><li>AcceptSecurityContext </li></ul>Secur32.dll
    17. 19. <ul><li>Waffle Provides Windows Authentication and Authorization Functions </li></ul><ul><li>Filters and Providers for Application Servers Tomcat, Jetty, WebSphere, etc. </li></ul><ul><li>Open-Source </li></ul>http://waffle.codeplex.com
    18. 20. <ul><li>Waffle-jna.jar + jna.jar + platform.jar </li></ul><ul><li>WEB-INFweb.xml </li></ul><ul><ul><li><filter> </li></ul></ul><ul><ul><li>   <filter-name>SecurityFilter</filter-name> </li></ul></ul><ul><ul><li>   <filter-class>waffle.servlet.NegotiateSecurityFilter</filter-class> </li></ul></ul><ul><ul><li></filter> </li></ul></ul><ul><ul><li><filter-mapping> </li></ul></ul><ul><ul><li>   <filter-name>SecurityFilter</filter-name> </li></ul></ul><ul><ul><li>   <url-pattern>/*</url-pattern> </li></ul></ul><ul><ul><li></filter-mapping> </li></ul></ul><ul><li>JSP Page </li></ul><ul><ul><li><%= request.getUserPrincipal().getName() %> </li></ul></ul>
    19. 21. <ul><li>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…HQAAAA9SRy02NDEwSU5URVJORVdT HTTP/1.1 200 OK WWW-Authenticate: Negotiate oRswGaADCgEAoxIEEAEAAAB7J3i2ZZ/tlgAAAAA= </li></ul>
    20. 22. <ul><li>IWindowsAuthProvider </li></ul><ul><li>IWindowsAccount </li></ul><ul><li>IWindowsComputer </li></ul><ul><li>IWindowsDomain </li></ul><ul><li>IWindowsIdentity </li></ul><ul><ul><ul><li>IntPtr securityToken = Advapi32.LogonUser( username, domain, password); WindowsIdentity windowsIdentity = new WindowsIdentity(securityToken); return windowsIdentity.groups; </li></ul></ul></ul>