1 /* 2 * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.net; 27 28 import sun.net.www.protocol.http.AuthenticatorKeys; 29 30 /** 31 * The class Authenticator represents an object that knows how to obtain 32 * authentication for a network connection. Usually, it will do this 33 * by prompting the user for information. 34 * <p> 35 * Applications use this class by overriding {@link 36 * #getPasswordAuthentication()} in a sub-class. This method will 37 * typically use the various getXXX() accessor methods to get information 38 * about the entity requesting authentication. It must then acquire a 39 * username and password either by interacting with the user or through 40 * some other non-interactive means. The credentials are then returned 41 * as a {@link PasswordAuthentication} return value. 42 * <p> 43 * An instance of this concrete sub-class is then registered 44 * with the system by calling {@link #setDefault(Authenticator)}. 45 * When authentication is required, the system will invoke one of the 46 * requestPasswordAuthentication() methods which in turn will call the 47 * getPasswordAuthentication() method of the registered object. 48 * <p> 49 * All methods that request authentication have a default implementation 50 * that fails. 51 * 52 * @see java.net.Authenticator#setDefault(java.net.Authenticator) 53 * @see java.net.Authenticator#getPasswordAuthentication() 54 * 55 * @author Bill Foote 56 * @since 1.2 57 */ 58 59 // There are no abstract methods, but to be useful the user must 60 // subclass. 61 public abstract 62 class Authenticator { 63 64 // The system-wide authenticator object. See setDefault(). 65 private static volatile Authenticator theAuthenticator; 66 67 private String requestingHost; 68 private InetAddress requestingSite; 69 private int requestingPort; 70 private String requestingProtocol; 71 private String requestingPrompt; 72 private String requestingScheme; 73 private URL requestingURL; 74 private RequestorType requestingAuthType; 75 private final String key = AuthenticatorKeys.computeKey(this); 76 77 /** 78 * The type of the entity requesting authentication. 79 * 80 * @since 1.5 81 */ 82 public enum RequestorType { 83 /** 84 * Entity requesting authentication is a HTTP proxy server. 85 */ 86 PROXY, 87 /** 88 * Entity requesting authentication is a HTTP origin server. 89 */ 90 SERVER 91 } 92 reset()93 private void reset() { 94 requestingHost = null; 95 requestingSite = null; 96 requestingPort = -1; 97 requestingProtocol = null; 98 requestingPrompt = null; 99 requestingScheme = null; 100 requestingURL = null; 101 requestingAuthType = RequestorType.SERVER; 102 } 103 104 105 /** 106 * Sets the authenticator that will be used by the networking code 107 * when a proxy or an HTTP server asks for authentication. 108 * <p> 109 * First, if there is a security manager, its {@code checkPermission} 110 * method is called with a 111 * {@code NetPermission("setDefaultAuthenticator")} permission. 112 * This may result in a java.lang.SecurityException. 113 * 114 * @param a The authenticator to be set. If a is {@code null} then 115 * any previously set authenticator is removed. 116 * 117 * @throws SecurityException 118 * if a security manager exists and its 119 * {@code checkPermission} method doesn't allow 120 * setting the default authenticator. 121 * 122 * @see SecurityManager#checkPermission 123 * @see java.net.NetPermission 124 */ setDefault(Authenticator a)125 public static synchronized void setDefault(Authenticator a) { 126 SecurityManager sm = System.getSecurityManager(); 127 if (sm != null) { 128 NetPermission setDefaultPermission 129 = new NetPermission("setDefaultAuthenticator"); 130 sm.checkPermission(setDefaultPermission); 131 } 132 133 theAuthenticator = a; 134 } 135 136 /** 137 * Gets the default authenticator. 138 * First, if there is a security manager, its {@code checkPermission} 139 * method is called with a 140 * {@code NetPermission("requestPasswordAuthentication")} permission. 141 * This may result in a java.lang.SecurityException. 142 * Then the default authenticator, if set, is returned. 143 * Otherwise, {@code null} is returned. 144 * 145 * @return The default authenticator, if set, {@code null} otherwise. 146 * 147 * @throws SecurityException 148 * if a security manager exists and its 149 * {@code checkPermission} method doesn't allow 150 * requesting password authentication. 151 * @since 9 152 * @see SecurityManager#checkPermission 153 * @see java.net.NetPermission 154 */ getDefault()155 public static Authenticator getDefault() { 156 SecurityManager sm = System.getSecurityManager(); 157 if (sm != null) { 158 NetPermission requestPermission 159 = new NetPermission("requestPasswordAuthentication"); 160 sm.checkPermission(requestPermission); 161 } 162 return theAuthenticator; 163 } 164 165 /** 166 * Ask the authenticator that has been registered with the system 167 * for a password. 168 * <p> 169 * First, if there is a security manager, its {@code checkPermission} 170 * method is called with a 171 * {@code NetPermission("requestPasswordAuthentication")} permission. 172 * This may result in a java.lang.SecurityException. 173 * 174 * @param addr The InetAddress of the site requesting authorization, 175 * or null if not known. 176 * @param port the port for the requested connection 177 * @param protocol The protocol that's requesting the connection 178 * ({@link java.net.Authenticator#getRequestingProtocol()}) 179 * @param prompt A prompt string for the user 180 * @param scheme The authentication scheme 181 * 182 * @return The username/password, or null if one can't be gotten. 183 * 184 * @throws SecurityException 185 * if a security manager exists and its 186 * {@code checkPermission} method doesn't allow 187 * the password authentication request. 188 * 189 * @see SecurityManager#checkPermission 190 * @see java.net.NetPermission 191 */ requestPasswordAuthentication( InetAddress addr, int port, String protocol, String prompt, String scheme)192 public static PasswordAuthentication requestPasswordAuthentication( 193 InetAddress addr, 194 int port, 195 String protocol, 196 String prompt, 197 String scheme) { 198 199 SecurityManager sm = System.getSecurityManager(); 200 if (sm != null) { 201 NetPermission requestPermission 202 = new NetPermission("requestPasswordAuthentication"); 203 sm.checkPermission(requestPermission); 204 } 205 206 Authenticator a = theAuthenticator; 207 if (a == null) { 208 return null; 209 } else { 210 synchronized(a) { 211 a.reset(); 212 a.requestingSite = addr; 213 a.requestingPort = port; 214 a.requestingProtocol = protocol; 215 a.requestingPrompt = prompt; 216 a.requestingScheme = scheme; 217 return a.getPasswordAuthentication(); 218 } 219 } 220 } 221 222 /** 223 * Ask the authenticator that has been registered with the system 224 * for a password. This is the preferred method for requesting a password 225 * because the hostname can be provided in cases where the InetAddress 226 * is not available. 227 * <p> 228 * First, if there is a security manager, its {@code checkPermission} 229 * method is called with a 230 * {@code NetPermission("requestPasswordAuthentication")} permission. 231 * This may result in a java.lang.SecurityException. 232 * 233 * @param host The hostname of the site requesting authentication. 234 * @param addr The InetAddress of the site requesting authentication, 235 * or null if not known. 236 * @param port the port for the requested connection. 237 * @param protocol The protocol that's requesting the connection 238 * ({@link java.net.Authenticator#getRequestingProtocol()}) 239 * @param prompt A prompt string for the user which identifies the authentication realm. 240 * @param scheme The authentication scheme 241 * 242 * @return The username/password, or null if one can't be gotten. 243 * 244 * @throws SecurityException 245 * if a security manager exists and its 246 * {@code checkPermission} method doesn't allow 247 * the password authentication request. 248 * 249 * @see SecurityManager#checkPermission 250 * @see java.net.NetPermission 251 * @since 1.4 252 */ requestPasswordAuthentication( String host, InetAddress addr, int port, String protocol, String prompt, String scheme)253 public static PasswordAuthentication requestPasswordAuthentication( 254 String host, 255 InetAddress addr, 256 int port, 257 String protocol, 258 String prompt, 259 String scheme) { 260 261 SecurityManager sm = System.getSecurityManager(); 262 if (sm != null) { 263 NetPermission requestPermission 264 = new NetPermission("requestPasswordAuthentication"); 265 sm.checkPermission(requestPermission); 266 } 267 268 Authenticator a = theAuthenticator; 269 if (a == null) { 270 return null; 271 } else { 272 synchronized(a) { 273 a.reset(); 274 a.requestingHost = host; 275 a.requestingSite = addr; 276 a.requestingPort = port; 277 a.requestingProtocol = protocol; 278 a.requestingPrompt = prompt; 279 a.requestingScheme = scheme; 280 return a.getPasswordAuthentication(); 281 } 282 } 283 } 284 285 /** 286 * Ask the authenticator that has been registered with the system 287 * for a password. 288 * <p> 289 * First, if there is a security manager, its {@code checkPermission} 290 * method is called with a 291 * {@code NetPermission("requestPasswordAuthentication")} permission. 292 * This may result in a java.lang.SecurityException. 293 * 294 * @param host The hostname of the site requesting authentication. 295 * @param addr The InetAddress of the site requesting authorization, 296 * or null if not known. 297 * @param port the port for the requested connection 298 * @param protocol The protocol that's requesting the connection 299 * ({@link java.net.Authenticator#getRequestingProtocol()}) 300 * @param prompt A prompt string for the user 301 * @param scheme The authentication scheme 302 * @param url The requesting URL that caused the authentication 303 * @param reqType The type (server or proxy) of the entity requesting 304 * authentication. 305 * 306 * @return The username/password, or null if one can't be gotten. 307 * 308 * @throws SecurityException 309 * if a security manager exists and its 310 * {@code checkPermission} method doesn't allow 311 * the password authentication request. 312 * 313 * @see SecurityManager#checkPermission 314 * @see java.net.NetPermission 315 * 316 * @since 1.5 317 */ requestPasswordAuthentication( String host, InetAddress addr, int port, String protocol, String prompt, String scheme, URL url, RequestorType reqType)318 public static PasswordAuthentication requestPasswordAuthentication( 319 String host, 320 InetAddress addr, 321 int port, 322 String protocol, 323 String prompt, 324 String scheme, 325 URL url, 326 RequestorType reqType) { 327 328 SecurityManager sm = System.getSecurityManager(); 329 if (sm != null) { 330 NetPermission requestPermission 331 = new NetPermission("requestPasswordAuthentication"); 332 sm.checkPermission(requestPermission); 333 } 334 335 Authenticator a = theAuthenticator; 336 if (a == null) { 337 return null; 338 } else { 339 synchronized(a) { 340 a.reset(); 341 a.requestingHost = host; 342 a.requestingSite = addr; 343 a.requestingPort = port; 344 a.requestingProtocol = protocol; 345 a.requestingPrompt = prompt; 346 a.requestingScheme = scheme; 347 a.requestingURL = url; 348 a.requestingAuthType = reqType; 349 return a.getPasswordAuthentication(); 350 } 351 } 352 } 353 354 /** 355 * Ask the given {@code authenticator} for a password. If the given 356 * {@code authenticator} is null, the authenticator, if any, that has been 357 * registered with the system using {@link #setDefault(java.net.Authenticator) 358 * setDefault} is used. 359 * <p> 360 * First, if there is a security manager, its {@code checkPermission} 361 * method is called with a 362 * {@code NetPermission("requestPasswordAuthentication")} permission. 363 * This may result in a java.lang.SecurityException. 364 * 365 * @param authenticator the authenticator, or {@code null}. 366 * @param host The hostname of the site requesting authentication. 367 * @param addr The InetAddress of the site requesting authorization, 368 * or null if not known. 369 * @param port the port for the requested connection 370 * @param protocol The protocol that's requesting the connection 371 * ({@link java.net.Authenticator#getRequestingProtocol()}) 372 * @param prompt A prompt string for the user 373 * @param scheme The authentication scheme 374 * @param url The requesting URL that caused the authentication 375 * @param reqType The type (server or proxy) of the entity requesting 376 * authentication. 377 * 378 * @return The username/password, or {@code null} if one can't be gotten. 379 * 380 * @throws SecurityException 381 * if a security manager exists and its 382 * {@code checkPermission} method doesn't allow 383 * the password authentication request. 384 * 385 * @see SecurityManager#checkPermission 386 * @see java.net.NetPermission 387 * 388 * @since 9 389 */ requestPasswordAuthentication( Authenticator authenticator, String host, InetAddress addr, int port, String protocol, String prompt, String scheme, URL url, RequestorType reqType)390 public static PasswordAuthentication requestPasswordAuthentication( 391 Authenticator authenticator, 392 String host, 393 InetAddress addr, 394 int port, 395 String protocol, 396 String prompt, 397 String scheme, 398 URL url, 399 RequestorType reqType) { 400 401 SecurityManager sm = System.getSecurityManager(); 402 if (sm != null) { 403 NetPermission requestPermission 404 = new NetPermission("requestPasswordAuthentication"); 405 sm.checkPermission(requestPermission); 406 } 407 408 Authenticator a = authenticator == null ? theAuthenticator : authenticator; 409 if (a == null) { 410 return null; 411 } else { 412 return a.requestPasswordAuthenticationInstance(host, 413 addr, 414 port, 415 protocol, 416 prompt, 417 scheme, 418 url, 419 reqType); 420 } 421 } 422 423 /** 424 * Ask this authenticator for a password. 425 * 426 * @param host The hostname of the site requesting authentication. 427 * @param addr The InetAddress of the site requesting authorization, 428 * or null if not known. 429 * @param port the port for the requested connection 430 * @param protocol The protocol that's requesting the connection 431 * ({@link java.net.Authenticator#getRequestingProtocol()}) 432 * @param prompt A prompt string for the user 433 * @param scheme The authentication scheme 434 * @param url The requesting URL that caused the authentication 435 * @param reqType The type (server or proxy) of the entity requesting 436 * authentication. 437 * 438 * @return The username/password, or null if one can't be gotten 439 * 440 * @since 9 441 */ 442 public PasswordAuthentication requestPasswordAuthenticationInstance(String host, InetAddress addr, int port, String protocol, String prompt, String scheme, URL url, RequestorType reqType)443 requestPasswordAuthenticationInstance(String host, 444 InetAddress addr, 445 int port, 446 String protocol, 447 String prompt, 448 String scheme, 449 URL url, 450 RequestorType reqType) { 451 synchronized (this) { 452 this.reset(); 453 this.requestingHost = host; 454 this.requestingSite = addr; 455 this.requestingPort = port; 456 this.requestingProtocol = protocol; 457 this.requestingPrompt = prompt; 458 this.requestingScheme = scheme; 459 this.requestingURL = url; 460 this.requestingAuthType = reqType; 461 return this.getPasswordAuthentication(); 462 } 463 } 464 465 /** 466 * Gets the {@code hostname} of the 467 * site or proxy requesting authentication, or {@code null} 468 * if not available. 469 * 470 * @return the hostname of the connection requiring authentication, or null 471 * if it's not available. 472 * @since 1.4 473 */ getRequestingHost()474 protected final String getRequestingHost() { 475 return requestingHost; 476 } 477 478 /** 479 * Gets the {@code InetAddress} of the 480 * site requesting authorization, or {@code null} 481 * if not available. 482 * 483 * @return the InetAddress of the site requesting authorization, or null 484 * if it's not available. 485 */ getRequestingSite()486 protected final InetAddress getRequestingSite() { 487 return requestingSite; 488 } 489 490 /** 491 * Gets the port number for the requested connection. 492 * @return an {@code int} indicating the 493 * port for the requested connection. 494 */ getRequestingPort()495 protected final int getRequestingPort() { 496 return requestingPort; 497 } 498 499 /** 500 * Give the protocol that's requesting the connection. Often this 501 * will be based on a URL, but in a future JDK it could be, for 502 * example, "SOCKS" for a password-protected SOCKS5 firewall. 503 * 504 * @return the protocol, optionally followed by "/version", where 505 * version is a version number. 506 * 507 * @see java.net.URL#getProtocol() 508 */ getRequestingProtocol()509 protected final String getRequestingProtocol() { 510 return requestingProtocol; 511 } 512 513 /** 514 * Gets the prompt string given by the requestor. 515 * 516 * @return the prompt string given by the requestor (realm for 517 * http requests) 518 */ getRequestingPrompt()519 protected final String getRequestingPrompt() { 520 return requestingPrompt; 521 } 522 523 /** 524 * Gets the scheme of the requestor (the HTTP scheme 525 * for an HTTP firewall, for example). 526 * 527 * @return the scheme of the requestor 528 * 529 */ getRequestingScheme()530 protected final String getRequestingScheme() { 531 return requestingScheme; 532 } 533 534 /** 535 * Called when password authorization is needed. Subclasses should 536 * override the default implementation, which returns null. 537 * @return The PasswordAuthentication collected from the 538 * user, or null if none is provided. 539 */ getPasswordAuthentication()540 protected PasswordAuthentication getPasswordAuthentication() { 541 return null; 542 } 543 544 /** 545 * Returns the URL that resulted in this 546 * request for authentication. 547 * 548 * @since 1.5 549 * 550 * @return the requesting URL 551 * 552 */ getRequestingURL()553 protected URL getRequestingURL () { 554 return requestingURL; 555 } 556 557 /** 558 * Returns whether the requestor is a Proxy or a Server. 559 * 560 * @since 1.5 561 * 562 * @return the authentication type of the requestor 563 * 564 */ getRequestorType()565 protected RequestorType getRequestorType () { 566 return requestingAuthType; 567 } 568 getKey(Authenticator a)569 static String getKey(Authenticator a) { 570 return a.key; 571 } 572 static { 573 AuthenticatorKeys.setAuthenticatorKeyAccess(Authenticator::getKey); 574 } 575 } 576