diff --git a/libsoup/soup-auth-manager.c b/libsoup/soup-auth-manager.c
index b32ba900..c47b1f01 100644
--- a/libsoup/soup-auth-manager.c
+++ b/libsoup/soup-auth-manager.c
@@ -508,30 +508,14 @@ lookup_proxy_auth (SoupAuthManagerPrivate *priv, SoupMessage *msg)
 static void
 authenticate_auth (SoupAuthManager *manager, SoupAuth *auth,
 		   SoupMessage *msg, gboolean prior_auth_failed,
-		   gboolean proxy, gboolean can_interact)
+		   SoupURI* proxy_uri, gboolean can_interact)
 {
-	SoupAuthManagerPrivate *priv = manager->priv;
 	SoupURI *uri;
 
 	if (!soup_auth_can_authenticate (auth))
 		return;
 
-	if (proxy) {
-		SoupMessageQueue *queue;
-		SoupMessageQueueItem *item;
-
-		queue = soup_session_get_queue (priv->session);
-		item = soup_message_queue_lookup (queue, msg);
-		if (!item)
-			return;
-
-		/* When loaded from the disk cache, the connection is NULL. */
-		uri = item->conn ? soup_connection_get_proxy_uri (item->conn) : NULL;
-		soup_message_queue_item_unref (item);
-		if (!uri)
-			return;
-	} else
-		uri = soup_message_get_uri (msg);
+	uri = proxy_uri ? proxy_uri : soup_message_get_uri (msg);
 
 	/* If a password is specified explicitly in the URI, use it
 	 * even if the auth had previously already been authenticated.
@@ -630,7 +614,7 @@ auth_got_headers (SoupMessage *msg, gpointer manager)
 
 	/* If we need to authenticate, try to do it. */
 	authenticate_auth (manager, auth, msg,
-			   prior_auth_failed, FALSE, TRUE);
+			   prior_auth_failed, NULL, TRUE);
 	soup_message_set_auth (msg, auth);
 	g_object_unref (auth);
 	g_mutex_unlock (&priv->lock);
@@ -663,11 +647,31 @@ auth_got_body (SoupMessage *msg, gpointer manager)
 	g_mutex_unlock (&priv->lock);
 }
 
+static SoupURI *
+soup_auth_manager_get_proxy_uri (SoupAuthManager *manager, SoupMessage *msg)
+{
+	SoupMessageQueue *queue;
+	SoupMessageQueueItem *item;
+	SoupURI *uri;
+
+	queue = soup_session_get_queue (manager->priv->session);
+	item = soup_message_queue_lookup (queue, msg);
+	if (!item)
+		return NULL;
+
+	/* When loaded from the disk cache, the connection is NULL. */
+	uri = item->conn ? soup_connection_get_proxy_uri (item->conn) : NULL;
+	soup_message_queue_item_unref (item);
+
+	return uri;
+}
+
 static void
 proxy_auth_got_headers (SoupMessage *msg, gpointer manager)
 {
 	SoupAuthManagerPrivate *priv = SOUP_AUTH_MANAGER (manager)->priv;
 	SoupAuth *auth = NULL, *prior_auth;
+	SoupURI *proxy_uri;
 	gboolean prior_auth_failed = FALSE;
 
 	g_mutex_lock (&priv->lock);
@@ -682,8 +686,17 @@ proxy_auth_got_headers (SoupMessage *msg, gpointer manager)
 	if (!(soup_message_get_flags (msg) & SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE))
 		auth = priv->proxy_auth ? g_object_ref (priv->proxy_auth) : NULL;
 
+	proxy_uri = soup_auth_manager_get_proxy_uri (manager, msg);
+
 	if (!auth) {
 		auth = create_auth (priv, msg);
+		if (proxy_uri) {
+			g_object_set (auth,
+				      SOUP_AUTH_HOST, proxy_uri->host,
+				      SOUP_AUTH_PORT, proxy_uri->port,
+				      NULL);
+		}
+
 		if (!auth) {
 			g_mutex_unlock (&priv->lock);
 			return;
@@ -692,9 +705,11 @@ proxy_auth_got_headers (SoupMessage *msg, gpointer manager)
 			priv->proxy_auth = g_object_ref (auth);
 	}
 
-	/* If we need to authenticate, try to do it. */
-	authenticate_auth (manager, auth, msg,
-			   prior_auth_failed, TRUE, TRUE);
+	if (proxy_uri) {
+		/* If we need to authenticate, try to do it. */
+		authenticate_auth (manager, auth, msg,
+				   prior_auth_failed, proxy_uri, TRUE);
+	}
 	soup_message_set_proxy_auth (msg, auth);
 	g_object_unref (auth);
 	g_mutex_unlock (&priv->lock);
@@ -735,7 +750,7 @@ auth_msg_starting (SoupMessage *msg, gpointer manager)
 	if (msg->method != SOUP_METHOD_CONNECT) {
 		auth = lookup_auth (priv, msg);
 		if (auth) {
-			authenticate_auth (manager, auth, msg, FALSE, FALSE, FALSE);
+			authenticate_auth (manager, auth, msg, FALSE, NULL, FALSE);
 			if (!soup_auth_is_ready (auth, msg))
 				auth = NULL;
 		}
@@ -745,7 +760,11 @@ auth_msg_starting (SoupMessage *msg, gpointer manager)
 
 	auth = lookup_proxy_auth (priv, msg);
 	if (auth) {
-		authenticate_auth (manager, auth, msg, FALSE, TRUE, FALSE);
+		SoupURI *proxy_uri;
+
+		proxy_uri = soup_auth_manager_get_proxy_uri (manager, msg);
+		if (proxy_uri)
+			authenticate_auth (manager, auth, msg, FALSE, proxy_uri, FALSE);
 		if (!soup_auth_is_ready (auth, msg))
 			auth = NULL;
 	}
diff --git a/libsoup/soup-auth.c b/libsoup/soup-auth.c
index 00aa405e..186410a5 100644
--- a/libsoup/soup-auth.c
+++ b/libsoup/soup-auth.c
@@ -37,6 +37,7 @@
 typedef struct {
 	gboolean proxy;
 	char *host;
+	guint port;
 } SoupAuthPrivate;
 
 G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (SoupAuth, soup_auth, G_TYPE_OBJECT)
@@ -47,6 +48,7 @@ enum {
 	PROP_SCHEME_NAME,
 	PROP_REALM,
 	PROP_HOST,
+	PROP_PORT,
 	PROP_IS_FOR_PROXY,
 	PROP_IS_AUTHENTICATED,
 
@@ -86,6 +88,9 @@ soup_auth_set_property (GObject *object, guint prop_id,
 		g_free (priv->host);
 		priv->host = g_value_dup_string (value);
 		break;
+	case PROP_PORT:
+		priv->port = g_value_get_uint (value);
+		break;
 	case PROP_IS_FOR_PROXY:
 		priv->proxy = g_value_get_boolean (value);
 		break;
@@ -116,6 +121,9 @@ soup_auth_get_property (GObject *object, guint prop_id,
 			g_free (priv->host);
 		g_value_set_string (value, soup_auth_get_host (auth));
 		break;
+	case PROP_PORT:
+		g_value_set_uint (value, soup_auth_get_port (auth));
+		break;
 	case PROP_IS_FOR_PROXY:
 		g_value_set_boolean (value, priv->proxy);
 		break;
@@ -186,6 +194,20 @@ soup_auth_class_init (SoupAuthClass *auth_class)
 				     NULL,
 				     G_PARAM_READWRITE));
 	/**
+	 * SOUP_AUTH_PORT:
+	 *
+	 * An alias for the #SoupAuth:port property. (The
+	 * port of the host being authenticated to.)
+	 **/
+	g_object_class_install_property (
+		object_class, PROP_PORT,
+		g_param_spec_uint (SOUP_AUTH_PORT,
+				   "Port",
+				   "Authentication port",
+				   0, G_MAXUINT, 0,
+				   G_PARAM_READWRITE));
+
+	/**
 	 * SOUP_AUTH_IS_FOR_PROXY:
 	 *
 	 * An alias for the #SoupAuth:is-for-proxy property. (Whether
@@ -234,14 +256,17 @@ soup_auth_new (GType type, SoupMessage *msg, const char *auth_header)
 	SoupAuth *auth;
 	GHashTable *params;
 	const char *scheme, *realm;
+	SoupURI *uri;
 
 	g_return_val_if_fail (g_type_is_a (type, SOUP_TYPE_AUTH), NULL);
 	g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL);
 	g_return_val_if_fail (auth_header != NULL, NULL);
 
+	uri = soup_message_get_uri (msg);
 	auth = g_object_new (type,
 			     SOUP_AUTH_IS_FOR_PROXY, (msg->status_code == SOUP_STATUS_PROXY_UNAUTHORIZED),
-			     SOUP_AUTH_HOST, soup_message_get_uri (msg)->host,
+			     SOUP_AUTH_HOST, uri->host,
+			     SOUP_AUTH_PORT, uri->port,
 			     NULL);
 
 	scheme = soup_auth_get_scheme_name (auth);
@@ -391,6 +416,24 @@ soup_auth_get_host (SoupAuth *auth)
 }
 
 /**
+ * soup_auth_get_port:
+ * @auth: a #SoupAuth
+ *
+ * Returns the port that @auth is associated with.
+ *
+ * Return value: the port
+ **/
+guint
+soup_auth_get_port (SoupAuth *auth)
+{
+	SoupAuthPrivate *priv = soup_auth_get_instance_private (auth);
+
+	g_return_val_if_fail (SOUP_IS_AUTH (auth), 0);
+
+	return priv->port;
+}
+
+/**
  * soup_auth_get_realm:
  * @auth: a #SoupAuth
  *
diff --git a/libsoup/soup-auth.h b/libsoup/soup-auth.h
index 0defcc65..1bead19b 100644
--- a/libsoup/soup-auth.h
+++ b/libsoup/soup-auth.h
@@ -58,6 +58,7 @@ typedef struct {
 #define SOUP_AUTH_SCHEME_NAME      "scheme-name"
 #define SOUP_AUTH_REALM            "realm"
 #define SOUP_AUTH_HOST             "host"
+#define SOUP_AUTH_PORT             "port"
 #define SOUP_AUTH_IS_FOR_PROXY     "is-for-proxy"
 #define SOUP_AUTH_IS_AUTHENTICATED "is-authenticated"
 
@@ -79,6 +80,8 @@ SOUP_AVAILABLE_IN_2_4
 const char *soup_auth_get_scheme_name       (SoupAuth      *auth);
 SOUP_AVAILABLE_IN_2_4
 const char *soup_auth_get_host              (SoupAuth      *auth);
+SOUP_AVAILABLE_IN_2_58
+guint       soup_auth_get_port              (SoupAuth      *auth);
 SOUP_AVAILABLE_IN_2_4
 const char *soup_auth_get_realm             (SoupAuth      *auth);
 SOUP_AVAILABLE_IN_2_4
diff --git a/tests/proxy-test.c b/tests/proxy-test.c
index 1d68aa05..f42fb4ac 100644
--- a/tests/proxy-test.c
+++ b/tests/proxy-test.c
@@ -45,9 +45,23 @@ authenticate (SoupSession *session, SoupMessage *msg,
 	      SoupAuth *auth, gboolean retrying, gpointer data)
 {
 	if (msg->status_code == SOUP_STATUS_UNAUTHORIZED) {
+		SoupURI *uri;
+
+		uri = soup_message_get_uri (msg);
+		g_assert_cmpstr (uri->host, ==, soup_auth_get_host (auth));
+		g_assert_cmpuint (uri->port, ==, soup_auth_get_port (auth));
+
 		soup_test_assert (!soup_auth_is_for_proxy (auth),
 				  "got proxy auth object for 401");
 	} else if (msg->status_code == SOUP_STATUS_PROXY_UNAUTHORIZED) {
+		int proxy = GPOINTER_TO_INT(data);
+		SoupURI *proxy_uri;
+
+		proxy_uri = soup_uri_new (proxies[proxy]);
+		g_assert_cmpstr (proxy_uri->host, ==, soup_auth_get_host (auth));
+		g_assert_cmpuint (proxy_uri->port, ==, soup_auth_get_port (auth));
+		soup_uri_free (proxy_uri);
+
 		soup_test_assert (soup_auth_is_for_proxy (auth),
 				  "got regular auth object for 407");
 	} else {
@@ -100,7 +114,7 @@ test_url (const char *url, int proxy, guint expected,
 					 SOUP_SESSION_SSL_STRICT, FALSE,
 					 NULL);
 	g_signal_connect (session, "authenticate",
-			  G_CALLBACK (authenticate), NULL);
+			  G_CALLBACK (authenticate), GINT_TO_POINTER (proxy));
 	if (close) {
 		/* FIXME g_test_bug ("611663") */
 		g_signal_connect (session, "request-started",
@@ -152,7 +166,7 @@ test_url_new_api (const char *url, int proxy, guint expected,
 					 NULL);
 
 	g_signal_connect (session, "authenticate",
-			  G_CALLBACK (authenticate), NULL);
+			  G_CALLBACK (authenticate), GINT_TO_POINTER (proxy));
 	if (close) {
 		/* FIXME g_test_bug ("611663") */
 		g_signal_connect (session, "request-started",
@@ -384,7 +398,7 @@ do_proxy_auth_cache_test (void)
 					 SOUP_SESSION_ADD_FEATURE, cache,
 					 NULL);
 	g_signal_connect (session, "authenticate",
-			  G_CALLBACK (authenticate), NULL);
+			  G_CALLBACK (authenticate), GINT_TO_POINTER (AUTH_PROXY));
 
 	url = g_strconcat (HTTP_SERVER, "/Basic/realm1/", NULL);
 
