Does Waffle support the implementation of the "Client" side?

Sep 7, 2010 at 4:55 AM

Hello

Does Waffle have support to be used to implement the HTTP "client" side to perform authentication against NTLMv2/SPNEGO secured services?

Can you point me to any samples or code I could use to investigate this further

thanks

asankha

Coordinator
Sep 7, 2010 at 5:13 AM
Yes. You don't actually need Waffle for client-side, just JNA.

There're plenty of examples in tests that manufacture the client-side WWW-Authenticate headers. For example, NegotiateSecurityFilterTests.testNegotiate implements both client and server (should be trivial to keep only client).

 

 

 

 

Sep 7, 2010 at 10:32 AM
Edited Sep 7, 2010 at 10:35 AM

I'm using waffle to do both web browser and swing application single sing on to web/application server. Here is how swing client performs SSO

 

			WindowsSecurityContextImpl ctx = new WindowsSecurityContextImpl();
			ctx.setCredentialsHandle(WindowsCredentialsHandleImpl.getCurrent(securityPackage).getHandle());

			SecBufferDesc tokenBuffer = null;
			CtxtHandle cth = null;
			boolean cont;
			try {
				String spn = serverHost == null ? null : "AS/" + serverHost;
				do {
					ctx.initialize(spn, cth, tokenBuffer, Sspi.ISC_REQ_CONNECTION);
					cth = ctx.getHandle();
					byte[] token = ctx.getToken();
					cont = ctx.getContinue();
					if (cont || token != null && token.length > 0) {
						byte[] token2 = auth.auth(token);
						tokenBuffer = null;
						if (token2 != null) {
							tokenBuffer = new SecBufferDesc(Sspi.SECBUFFER_TOKEN, token2);
						}
					}
				} while (cont);
			} catch (RemoteException e) {
				throw new EmanException(e);
			}

Sep 7, 2010 at 10:44 AM

Thanks for the reply Jnx

My main use case will be from Linux/Unix environments, when integrating with Windows authentication secured services. I am not yet familiar with Windows based authentication either.

I guess the above code would even fetch the credentials of the user currently logged into a Windows box from JNA. What would need to change if I want to run the client from a Linux/Unix environment against a service thats secured by SPNEGO with Kerberos?

thanks

asankha

Coordinator
Sep 7, 2010 at 12:14 PM
asankha wrote:

My main use case will be from Linux/Unix environments, when integrating with Windows authentication secured services. I am not yet familiar with Windows based authentication either.

I guess the above code would even fetch the credentials of the user currently logged into a Windows box from JNA. What would need to change if I want to run the client from a Linux/Unix environment against a service thats secured by SPNEGO with Kerberos?

Waffle won't do that for you. It uses Windows API, which doesn't exist on *nix.

In order to do NTLM / Kerberos with a Windows server the client must be joined to the Active Directory domain. You should check out LikeWise, it claims to do all of that. There's a workitem to port Waffle to unix using the Likewise SSPI implementation - something that likewise folks said is possible.

Sep 7, 2010 at 5:10 PM
Edited Sep 7, 2010 at 5:11 PM

You can use kerberos to authenticate linux clients against active directory. Google will find you a lot of guides how to do it ... http://www.google.cz/search?q=linux+client+kerberos+active+directory .  Java supports Kerberos authentication, the only thing it needs is TGT (Ticket Granting Ticket) and proper krb5.conf/login.conf . Here is client part of kerberos authentication.

 

LoginContext loginContext = new LoginContext("kerberos-client-sso");
loginContext.login();

GSSContext context = null;
// work-around to GSSContext/AD timestamp vs sequence field replay bug
Util.sleep(50);

GSSName serverName = manager.createName("AS@" + serverHost, GSSName.NT_HOSTBASED_SERVICE, KERBEROS_OID);
final PrivilegedExceptionAction<GSSCredential> action = new PrivilegedExceptionAction<GSSCredential>() {
	public GSSCredential run() throws GSSException {
		return manager.createCredential(null, GSSCredential.DEFAULT_LIFETIME, KERBEROS_OID,
				GSSCredential.INITIATE_ONLY);
	}
};
GSSCredential credential = Subject.doAs(loginContext.getSubject(), action);

context = manager.createContext(serverName, KERBEROS_OID, credential, GSSContext.DEFAULT_LIFETIME);
context.requestMutualAuth(true);
context.requestConf(true);
context.requestInteg(true);
context.requestReplayDet(true);
context.requestSequenceDet(true);
context.requestCredDeleg(false);

byte[] token = new byte[0];
boolean cont;
do {
	token = context.initSecContext(token, 0, token.length);
	cont = !context.isEstablished();
	if (cont || token != null && token.length > 0) {
		token = auth.auth(token);
	}
} while (cont);

 

 

 

Jan 8, 2011 at 8:53 AM
dblock wrote:
Yes. You don't actually need Waffle for client-side, just JNA.

There're plenty of examples in tests that manufacture the client-side WWW-Authenticate headers. For example, NegotiateSecurityFilterTests.testNegotiate implements both client and server (should be trivial to keep only client).

 

Hi dblock,

I downloaded the WAFFLE project, but I can not find "NegotiateSecurityFilterTests.testNegotiate".

I have the same problem:

I want to login from client to a remote machine, but I dont know how to build the response of theType-3-Message

her is my dataflow:

GET / HTTP/1.1
Accept: image/jpeg, image/gif, image/pjpeg, application/x-shockwave-flash, application/x-ms-application, application/xaml+xml, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
Accept-Language: de-DE
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; GTB6.6; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C; .NET4.0E; InfoPath.3)
Accept-Encoding: gzip, deflate
Host: 192.168.10.200:32768

HTTP/1.1 401 Unauthorized
Server: Cassini/4.0.1.8
Date: Sat, 08 Jan 2011 08:13:47 GMT
Content-Length: 1195
WWW-Authenticate: NTLM

GET / HTTP/1.1
Accept: image/jpeg, image/gif, image/pjpeg, application/x-shockwave-flash, application/x-ms-application, application/xaml+xml, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
Accept-Language: de-DE
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; GTB6.6; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C; .NET4.0E; InfoPath.3)
Accept-Encoding: gzip, deflate
Host: 192.168.10.200:32768
Authorization: NTLM TlRMTVNTUAABAAAAl7II4gcABwAyAAAACgAKACgAAAAGAbAdAAAAD1AxODMtUDZUVjJWUFNJTFZB

HTTP/1.1 401 Unauthorized
Server: Cassini/4.0.1.8
Date: Sat, 08 Jan 2011 08:16:24 GMT
Content-Length: 1195
WWW-Authenticate: NTLM TlRMTVNTUAACAAAAFAAUADgAAAAVworiXSeip92qgDwwM4MCAAAAAHAAcABMAAAABgGwHQAAAA9QADEAOAAzAC0AUAA2AFQAVgAyAAIAFABQADEAOAAzAC0AUAA2AFQAVgAyAAEAFABQADEAOAAzAC0AUAA2 ....

 

 

maybe you can help with  a c# codesnippet

Thank You

 

 

Coordinator
Jan 10, 2011 at 3:07 PM

Okay, so you're writing this in C#, I was confused ;) I assume the output above is an HTTP trace from your code?

Find WindowsAuthProviderUnitTests.cs. It has a test called testNegotiate.

        public void TestNegotiate()
        {
            string package = "Negotiate";
            WindowsAuthProviderImpl provider = new WindowsAuthProviderImpl();
            WindowsSecurityContext initContext = WindowsSecurityContext.GetCurrent(package,
                WindowsIdentity.GetCurrent().Name, Secur32.ISC_REQ_CONNECTION, Secur32.SECURITY_NATIVE_DREP);
            IWindowsSecurityContext continueContext = initContext;
            IWindowsSecurityContext responseContext = null;
            string connectionId = Guid.NewGuid().ToString();
            do
            {
                responseContext = provider.AcceptSecurityToken(connectionId, continueContext.Token, package,
                    Secur32.ISC_REQ_CONNECTION, Secur32.SECURITY_NATIVE_DREP);
                if (responseContext.Token != null)
                {
                    Console.WriteLine("  Token: {0}", Convert.ToBase64String(responseContext.Token));
                    Console.WriteLine("  Continue: {0}", responseContext.Continue);
                }
                continueContext = new WindowsSecurityContext(initContext, responseContext.Token,
                    Secur32.ISC_REQ_CONNECTION, Secur32.SECURITY_NATIVE_DREP);
            } while (responseContext.Continue);

            Assert.IsFalse(responseContext.Continue);
            Console.WriteLine(responseContext.Identity.Fqn);
        }

So this is both clint and server. The server calls AcceptSecurityToken and the client side is all the init and continueContext. So instead of the AcceptSecurityToken call you'll be sending the continueContext.Token string to the server and it will be returning you a responseContext.Token string in the WWW-Authenticate: header. I suggest writing a test against a working NTLM server (and share it here).

Btw, the entire Microsoft HTTP stack supports Negotiate and NTLM, maybe you don't need Waffle at all?

Mar 10, 2011 at 3:37 PM

Hi there

I'm trying to use the example shown but stuck with 

byte[] token2 = auth.auth(token);

Can anyone please help me. What is an auth? Class?

Coordinator
Mar 11, 2011 at 2:18 PM
kmoes wrote:

Hi there

I'm trying to use the example shown but stuck with 

byte[] token2 = auth.auth(token);

Can anyone please help me. What is an auth? Class?

Scratch my previous comment. It's some client-side swing authenticator, @jnx should be able to expand on it.