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 * Constructor for subclasses to call. 79 */ 80 public Authenticator() {} 81 82 /** 83 * The type of the entity requesting authentication. 84 * 85 * @since 1.5 86 */ 87 public enum RequestorType { 88 /** 89 * Entity requesting authentication is a HTTP proxy server. 90 */ 91 PROXY, 92 /** 93 * Entity requesting authentication is a HTTP origin server. 94 */ 95 SERVER 96 } 97 98 private void reset() { 99 requestingHost = null; 100 requestingSite = null; 101 requestingPort = -1; 102 requestingProtocol = null; 103 requestingPrompt = null; 104 requestingScheme = null; 105 requestingURL = null; 106 requestingAuthType = RequestorType.SERVER; 107 } 108 109 110 /** 111 * Sets the authenticator that will be used by the networking code 112 * when a proxy or an HTTP server asks for authentication. 113 * <p> 114 * First, if there is a security manager, its {@code checkPermission} 115 * method is called with a 116 * {@code NetPermission("setDefaultAuthenticator")} permission. 117 * This may result in a java.lang.SecurityException. 118 * 119 * @param a The authenticator to be set. If a is {@code null} then 120 * any previously set authenticator is removed. 121 * 122 * @throws SecurityException 123 * if a security manager exists and its 124 * {@code checkPermission} method doesn't allow 125 * setting the default authenticator. 126 * 127 * @see SecurityManager#checkPermission 128 * @see java.net.NetPermission 129 */ 130 public static synchronized void setDefault(Authenticator a) { 131 SecurityManager sm = System.getSecurityManager(); 132 if (sm != null) { 133 NetPermission setDefaultPermission 134 = new NetPermission("setDefaultAuthenticator"); 135 sm.checkPermission(setDefaultPermission); 136 } 137 138 theAuthenticator = a; 139 } 140 141 /** 142 * Gets the default authenticator. 143 * First, if there is a security manager, its {@code checkPermission} 144 * method is called with a 145 * {@code NetPermission("requestPasswordAuthentication")} permission. 146 * This may result in a java.lang.SecurityException. 147 * Then the default authenticator, if set, is returned. 148 * Otherwise, {@code null} is returned. 149 * 150 * @return The default authenticator, if set, {@code null} otherwise. 151 * 152 * @throws SecurityException 153 * if a security manager exists and its 154 * {@code checkPermission} method doesn't allow 155 * requesting password authentication. 156 * @since 9 157 * @see SecurityManager#checkPermission 158 * @see java.net.NetPermission 159 */ 160 public static Authenticator getDefault() { 161 SecurityManager sm = System.getSecurityManager(); 162 if (sm != null) { 163 NetPermission requestPermission 164 = new NetPermission("requestPasswordAuthentication"); 165 sm.checkPermission(requestPermission); 166 } 167 return theAuthenticator; 168 } 169 170 /** 171 * Ask the authenticator that has been registered with the system 172 * for a password. 173 * <p> 174 * First, if there is a security manager, its {@code checkPermission} 175 * method is called with a 176 * {@code NetPermission("requestPasswordAuthentication")} permission. 177 * This may result in a java.lang.SecurityException. 178 * 179 * @param addr The InetAddress of the site requesting authorization, 180 * or null if not known. 181 * @param port the port for the requested connection 182 * @param protocol The protocol that's requesting the connection 183 * ({@link java.net.Authenticator#getRequestingProtocol()}) 184 * @param prompt A prompt string for the user 185 * @param scheme The authentication scheme 186 * 187 * @return The username/password, or null if one can't be gotten. 188 * 189 * @throws SecurityException 190 * if a security manager exists and its 191 * {@code checkPermission} method doesn't allow 192 * the password authentication request. 193 * 194 * @see SecurityManager#checkPermission 195 * @see java.net.NetPermission 196 */ 197 public static PasswordAuthentication requestPasswordAuthentication( 198 InetAddress addr, 199 int port, 200 String protocol, 201 String prompt, 202 String scheme) { 203 204 SecurityManager sm = System.getSecurityManager(); 205 if (sm != null) { 206 NetPermission requestPermission 207 = new NetPermission("requestPasswordAuthentication"); 208 sm.checkPermission(requestPermission); 209 } 210 211 Authenticator a = theAuthenticator; 212 if (a == null) { 213 return null; 214 } else { 215 synchronized(a) { 216 a.reset(); 217 a.requestingSite = addr; 218 a.requestingPort = port; 219 a.requestingProtocol = protocol; 220 a.requestingPrompt = prompt; 221 a.requestingScheme = scheme; 222 return a.getPasswordAuthentication(); 223 } 224 } 225 } 226 227 /** 228 * Ask the authenticator that has been registered with the system 229 * for a password. This is the preferred method for requesting a password 230 * because the hostname can be provided in cases where the InetAddress 231 * is not available. 232 * <p> 233 * First, if there is a security manager, its {@code checkPermission} 234 * method is called with a 235 * {@code NetPermission("requestPasswordAuthentication")} permission. 236 * This may result in a java.lang.SecurityException. 237 * 238 * @param host The hostname of the site requesting authentication. 239 * @param addr The InetAddress of the site requesting authentication, 240 * or null if not known. 241 * @param port the port for the requested connection. 242 * @param protocol The protocol that's requesting the connection 243 * ({@link java.net.Authenticator#getRequestingProtocol()}) 244 * @param prompt A prompt string for the user which identifies the authentication realm. 245 * @param scheme The authentication scheme 246 * 247 * @return The username/password, or null if one can't be gotten. 248 * 249 * @throws SecurityException 250 * if a security manager exists and its 251 * {@code checkPermission} method doesn't allow 252 * the password authentication request. 253 * 254 * @see SecurityManager#checkPermission 255 * @see java.net.NetPermission 256 * @since 1.4 257 */ 258 public static PasswordAuthentication requestPasswordAuthentication( 259 String host, 260 InetAddress addr, 261 int port, 262 String protocol, 263 String prompt, 264 String scheme) { 265 266 SecurityManager sm = System.getSecurityManager(); 267 if (sm != null) { 268 NetPermission requestPermission 269 = new NetPermission("requestPasswordAuthentication"); 270 sm.checkPermission(requestPermission); 271 } 272 273 Authenticator a = theAuthenticator; 274 if (a == null) { 275 return null; 276 } else { 277 synchronized(a) { 278 a.reset(); 279 a.requestingHost = host; 280 a.requestingSite = addr; 281 a.requestingPort = port; 282 a.requestingProtocol = protocol; 283 a.requestingPrompt = prompt; 284 a.requestingScheme = scheme; 285 return a.getPasswordAuthentication(); 286 } 287 } 288 } 289 290 /** 291 * Ask the authenticator that has been registered with the system 292 * for a password. 293 * <p> 294 * First, if there is a security manager, its {@code checkPermission} 295 * method is called with a 296 * {@code NetPermission("requestPasswordAuthentication")} permission. 297 * This may result in a java.lang.SecurityException. 298 * 299 * @param host The hostname of the site requesting authentication. 300 * @param addr The InetAddress of the site requesting authorization, 301 * or null if not known. 302 * @param port the port for the requested connection 303 * @param protocol The protocol that's requesting the connection 304 * ({@link java.net.Authenticator#getRequestingProtocol()}) 305 * @param prompt A prompt string for the user 306 * @param scheme The authentication scheme 307 * @param url The requesting URL that caused the authentication 308 * @param reqType The type (server or proxy) of the entity requesting 309 * authentication. 310 * 311 * @return The username/password, or null if one can't be gotten. 312 * 313 * @throws SecurityException 314 * if a security manager exists and its 315 * {@code checkPermission} method doesn't allow 316 * the password authentication request. 317 * 318 * @see SecurityManager#checkPermission 319 * @see java.net.NetPermission 320 * 321 * @since 1.5 322 */ 323 public static PasswordAuthentication requestPasswordAuthentication( 324 String host, 325 InetAddress addr, 326 int port, 327 String protocol, 328 String prompt, 329 String scheme, 330 URL url, 331 RequestorType reqType) { 332 333 SecurityManager sm = System.getSecurityManager(); 334 if (sm != null) { 335 NetPermission requestPermission 336 = new NetPermission("requestPasswordAuthentication"); 337 sm.checkPermission(requestPermission); 338 } 339 340 Authenticator a = theAuthenticator; 341 if (a == null) { 342 return null; 343 } else { 344 synchronized(a) { 345 a.reset(); 346 a.requestingHost = host; 347 a.requestingSite = addr; 348 a.requestingPort = port; 349 a.requestingProtocol = protocol; 350 a.requestingPrompt = prompt; 351 a.requestingScheme = scheme; 352 a.requestingURL = url; 353 a.requestingAuthType = reqType; 354 return a.getPasswordAuthentication(); 355 } 356 } 357 } 358 359 /** 360 * Ask the given {@code authenticator} for a password. If the given 361 * {@code authenticator} is null, the authenticator, if any, that has been 362 * registered with the system using {@link #setDefault(java.net.Authenticator) 363 * setDefault} is used. 364 * <p> 365 * First, if there is a security manager, its {@code checkPermission} 366 * method is called with a 367 * {@code NetPermission("requestPasswordAuthentication")} permission. 368 * This may result in a java.lang.SecurityException. 369 * 370 * @param authenticator the authenticator, or {@code null}. 371 * @param host The hostname of the site requesting authentication. 372 * @param addr The InetAddress of the site requesting authorization, 373 * or null if not known. 374 * @param port the port for the requested connection 375 * @param protocol The protocol that's requesting the connection 376 * ({@link java.net.Authenticator#getRequestingProtocol()}) 377 * @param prompt A prompt string for the user 378 * @param scheme The authentication scheme 379 * @param url The requesting URL that caused the authentication 380 * @param reqType The type (server or proxy) of the entity requesting 381 * authentication. 382 * 383 * @return The username/password, or {@code null} if one can't be gotten. 384 * 385 * @throws SecurityException 386 * if a security manager exists and its 387 * {@code checkPermission} method doesn't allow 388 * the password authentication request. 389 * 390 * @see SecurityManager#checkPermission 391 * @see java.net.NetPermission 392 * 393 * @since 9 394 */ 395 public static PasswordAuthentication requestPasswordAuthentication( 396 Authenticator authenticator, 397 String host, 398 InetAddress addr, 399 int port, 400 String protocol, 401 String prompt, 402 String scheme, 403 URL url, 404 RequestorType reqType) { 405 406 SecurityManager sm = System.getSecurityManager(); 407 if (sm != null) { 408 NetPermission requestPermission 409 = new NetPermission("requestPasswordAuthentication"); 410 sm.checkPermission(requestPermission); 411 } 412 413 Authenticator a = authenticator == null ? theAuthenticator : authenticator; 414 if (a == null) { 415 return null; 416 } else { 417 return a.requestPasswordAuthenticationInstance(host, 418 addr, 419 port, 420 protocol, 421 prompt, 422 scheme, 423 url, 424 reqType); 425 } 426 } 427 428 /** 429 * Ask this authenticator for a password. 430 * 431 * @param host The hostname of the site requesting authentication. 432 * @param addr The InetAddress of the site requesting authorization, 433 * or null if not known. 434 * @param port the port for the requested connection 435 * @param protocol The protocol that's requesting the connection 436 * ({@link java.net.Authenticator#getRequestingProtocol()}) 437 * @param prompt A prompt string for the user 438 * @param scheme The authentication scheme 439 * @param url The requesting URL that caused the authentication 440 * @param reqType The type (server or proxy) of the entity requesting 441 * authentication. 442 * 443 * @return The username/password, or null if one can't be gotten 444 * 445 * @since 9 446 */ 447 public PasswordAuthentication 448 requestPasswordAuthenticationInstance(String host, 449 InetAddress addr, 450 int port, 451 String protocol, 452 String prompt, 453 String scheme, 454 URL url, 455 RequestorType reqType) { 456 synchronized (this) { 457 this.reset(); 458 this.requestingHost = host; 459 this.requestingSite = addr; 460 this.requestingPort = port; 461 this.requestingProtocol = protocol; 462 this.requestingPrompt = prompt; 463 this.requestingScheme = scheme; 464 this.requestingURL = url; 465 this.requestingAuthType = reqType; 466 return this.getPasswordAuthentication(); 467 } 468 } 469 470 /** 471 * Gets the {@code hostname} of the 472 * site or proxy requesting authentication, or {@code null} 473 * if not available. 474 * 475 * @return the hostname of the connection requiring authentication, or null 476 * if it's not available. 477 * @since 1.4 478 */ 479 protected final String getRequestingHost() { 480 return requestingHost; 481 } 482 483 /** 484 * Gets the {@code InetAddress} of the 485 * site requesting authorization, or {@code null} 486 * if not available. 487 * 488 * @return the InetAddress of the site requesting authorization, or null 489 * if it's not available. 490 */ 491 protected final InetAddress getRequestingSite() { 492 return requestingSite; 493 } 494 495 /** 496 * Gets the port number for the requested connection. 497 * @return an {@code int} indicating the 498 * port for the requested connection. 499 */ 500 protected final int getRequestingPort() { 501 return requestingPort; 502 } 503 504 /** 505 * Give the protocol that's requesting the connection. Often this 506 * will be based on a URL, but in a future JDK it could be, for 507 * example, "SOCKS" for a password-protected SOCKS5 firewall. 508 * 509 * @return the protocol, optionally followed by "/version", where 510 * version is a version number. 511 * 512 * @see java.net.URL#getProtocol() 513 */ 514 protected final String getRequestingProtocol() { 515 return requestingProtocol; 516 } 517 518 /** 519 * Gets the prompt string given by the requestor. 520 * 521 * @return the prompt string given by the requestor (realm for 522 * http requests) 523 */ 524 protected final String getRequestingPrompt() { 525 return requestingPrompt; 526 } 527 528 /** 529 * Gets the scheme of the requestor (the HTTP scheme 530 * for an HTTP firewall, for example). 531 * 532 * @return the scheme of the requestor 533 * 534 */ 535 protected final String getRequestingScheme() { 536 return requestingScheme; 537 } 538 539 /** 540 * Called when password authorization is needed. Subclasses should 541 * override the default implementation, which returns null. 542 * @return The PasswordAuthentication collected from the 543 * user, or null if none is provided. 544 */ 545 protected PasswordAuthentication getPasswordAuthentication() { 546 return null; 547 } 548 549 /** 550 * Returns the URL that resulted in this 551 * request for authentication. 552 * 553 * @since 1.5 554 * 555 * @return the requesting URL 556 * 557 */ 558 protected URL getRequestingURL () { 559 return requestingURL; 560 } 561 562 /** 563 * Returns whether the requestor is a Proxy or a Server. 564 * 565 * @since 1.5 566 * 567 * @return the authentication type of the requestor 568 * 569 */ 570 protected RequestorType getRequestorType () { 571 return requestingAuthType; 572 } 573 574 static String getKey(Authenticator a) { 575 return a.key; 576 } 577 static { 578 AuthenticatorKeys.setAuthenticatorKeyAccess(Authenticator::getKey); 579 } 580 }