From 23a0fee5182e76ddc1444a8d644bfc48f10d6b8b Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Thu, 18 Mar 2010 18:26:37 +0800 Subject: [PATCH] 6829283: HTTP/Negotiate: Autheticator triggered again when user cancels the first one Reviewed-by: chegar --- .../http/spnego/NegotiateCallbackHandler.java | 57 ++++++----- .../krb5/auto/HttpNegotiateServer.java | 99 +++++++++++++++---- 2 files changed, 112 insertions(+), 44 deletions(-) diff --git a/jdk/src/share/classes/sun/net/www/protocol/http/spnego/NegotiateCallbackHandler.java b/jdk/src/share/classes/sun/net/www/protocol/http/spnego/NegotiateCallbackHandler.java index f2c0f6cc254..1dd442ddfca 100644 --- a/jdk/src/share/classes/sun/net/www/protocol/http/spnego/NegotiateCallbackHandler.java +++ b/jdk/src/share/classes/sun/net/www/protocol/http/spnego/NegotiateCallbackHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2005-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2005-2010 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,43 +45,50 @@ public class NegotiateCallbackHandler implements CallbackHandler { private String username; private char[] password; + /** + * Authenticator asks for username and password in a single prompt, + * but CallbackHandler checks one by one. So, no matter which callback + * gets handled first, make sure Authenticator is only called once. + */ + private boolean answered; + private final HttpCallerInfo hci; public NegotiateCallbackHandler(HttpCallerInfo hci) { this.hci = hci; } + private void getAnswer() { + if (!answered) { + answered = true; + PasswordAuthentication passAuth = + Authenticator.requestPasswordAuthentication( + hci.host, hci.addr, hci.port, hci.protocol, + hci.prompt, hci.scheme, hci.url, hci.authType); + /** + * To be compatible with existing callback handler implementations, + * when the underlying Authenticator is canceled, username and + * password are assigned null. No exception is thrown. + */ + if (passAuth != null) { + username = passAuth.getUserName(); + password = passAuth.getPassword(); + } + } + } + public void handle(Callback[] callbacks) throws UnsupportedCallbackException, IOException { for (int i=0; i 1) { + throw new RuntimeException("Authenticator called twice"); + } + } + /** * Creates and starts an HTTP or proxy server that requires * Negotiate authentication.