src/java.base/share/classes/java/net/Authenticator.java
changeset 47216 71c04702a3d5
parent 42351 85ed90be0ae1
equal deleted inserted replaced
47215:4ebc2e2fb97c 47216:71c04702a3d5
       
     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 
       
    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      */
       
   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      */
       
   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      */
       
   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      */
       
   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      */
       
   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      */
       
   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
       
   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      */
       
   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      */
       
   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      */
       
   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      */
       
   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      */
       
   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      */
       
   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      */
       
   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      */
       
   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      */
       
   565     protected RequestorType getRequestorType () {
       
   566         return requestingAuthType;
       
   567     }
       
   568 
       
   569     static String getKey(Authenticator a) {
       
   570         return a.key;
       
   571     }
       
   572     static {
       
   573         AuthenticatorKeys.setAuthenticatorKeyAccess(Authenticator::getKey);
       
   574     }
       
   575 }