1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package java.net;
19
20/**
21 * An implementation of this class is able to obtain authentication information
22 * for a connection in several ways. For this purpose it has to set the default
23 * authenticator which extends {@code Authenticator} by {@code
24 * setDefault(Authenticator a)}. Then it should override {@code
25 * getPasswordAuthentication()} which dictates how the authentication info is
26 * obtained. Usually, it prompts the user for the required input.
27 *
28 * @see #setDefault
29 * @see #getPasswordAuthentication
30 */
31public abstract class Authenticator {
32
33    // the default authenticator that needs to be set
34    private static Authenticator thisAuthenticator;
35
36    private static final NetPermission requestPasswordAuthenticationPermission = new NetPermission(
37            "requestPasswordAuthentication"); //$NON-NLS-1$
38
39    private static final NetPermission setDefaultAuthenticatorPermission = new NetPermission(
40            "setDefaultAuthenticator"); //$NON-NLS-1$
41
42    // the requester connection info
43    private String host;
44
45    private InetAddress addr;
46
47    private int port;
48
49    private String protocol;
50
51    private String prompt;
52
53    private String scheme;
54
55    private URL url;
56
57    private RequestorType rt;
58
59    /**
60     * Returns the collected username and password for authorization. The
61     * subclass has to override this method to return a value different to the
62     * default which is {@code null}.
63     * <p>
64     * Returns {@code null} by default.
65     *
66     * @return collected password authentication data.
67     */
68    protected PasswordAuthentication getPasswordAuthentication() {
69        return null;
70    }
71
72    /**
73     * Returns the port of the connection that requests authorization.
74     *
75     * @return port of the connection.
76     */
77    protected final int getRequestingPort() {
78        return this.port;
79    }
80
81    /**
82     * Returns the address of the connection that requests authorization or
83     * {@code null} if unknown.
84     *
85     * @return address of the connection.
86     */
87    protected final InetAddress getRequestingSite() {
88        return this.addr;
89    }
90
91    /**
92     * Returns the realm (prompt string) of the connection that requests
93     * authorization.
94     *
95     * @return prompt string of the connection.
96     */
97    protected final String getRequestingPrompt() {
98        return this.prompt;
99    }
100
101    /**
102     * Returns the protocol of the connection that requests authorization.
103     *
104     * @return protocol of the connection.
105     */
106    protected final String getRequestingProtocol() {
107        return this.protocol;
108    }
109
110    /**
111     * Returns the scheme of the connection that requests authorization, for
112     * example HTTP Basic Authentication.
113     *
114     * @return scheme of the connection.
115     */
116    protected final String getRequestingScheme() {
117        return this.scheme;
118    }
119
120    /**
121     * If the permission check of the security manager does not result in a
122     * security exception, this method invokes the methods of the registered
123     * authenticator to get the authentication info.
124     *
125     * @return password authentication info or {@code null} if no authenticator
126     *         exists.
127     * @param rAddr
128     *            address of the connection that requests authentication.
129     * @param rPort
130     *            port of the connection that requests authentication.
131     * @param rProtocol
132     *            protocol of the connection that requests authentication.
133     * @param rPrompt
134     *            realm of the connection that requests authentication.
135     * @param rScheme
136     *            scheme of the connection that requests authentication.
137     * @throws SecurityException
138     *             if a security manager denies the password authentication
139     *             permission.
140     */
141    public static synchronized PasswordAuthentication requestPasswordAuthentication(
142            InetAddress rAddr, int rPort, String rProtocol, String rPrompt,
143            String rScheme) {
144        SecurityManager sm = System.getSecurityManager();
145        if (sm != null) {
146            sm.checkPermission(requestPasswordAuthenticationPermission);
147        }
148        if (thisAuthenticator == null) {
149            return null;
150        }
151        // set the requester info so it knows what it is requesting
152        // authentication for
153        thisAuthenticator.addr = rAddr;
154        thisAuthenticator.port = rPort;
155        thisAuthenticator.protocol = rProtocol;
156        thisAuthenticator.prompt = rPrompt;
157        thisAuthenticator.scheme = rScheme;
158        thisAuthenticator.rt = RequestorType.SERVER;
159
160        // returns the authentication info obtained by the registered
161        // Authenticator
162        return thisAuthenticator.getPasswordAuthentication();
163    }
164
165    /**
166     * Sets {@code a} as the default authenticator. It will be called whenever
167     * the realm that the URL is pointing to requires authorization. If there is
168     * a security manager set then the caller must have the appropriate {@code
169     * NetPermission}.
170     *
171     * @param a
172     *            authenticator which has to be set as default.
173     * @throws SecurityException
174     *             if a security manager denies the password authentication
175     *             permission.
176     */
177    public static void setDefault(Authenticator a) {
178        SecurityManager sm = System.getSecurityManager();
179        if (sm != null) {
180            sm.checkPermission(setDefaultAuthenticatorPermission);
181        }
182        thisAuthenticator = a;
183    }
184
185    /**
186     * If the permission check of the security manager does not result in a
187     * security exception, this method invokes the methods of the registered
188     * authenticator to get the authentication info.
189     *
190     * @return password authentication info or {@code null} if no authenticator
191     *         exists.
192     * @param rHost
193     *            host name of the connection that requests authentication.
194     * @param rAddr
195     *            address of the connection that requests authentication.
196     * @param rPort
197     *            port of the connection that requests authentication.
198     * @param rProtocol
199     *            protocol of the connection that requests authentication.
200     * @param rPrompt
201     *            realm of the connection that requests authentication.
202     * @param rScheme
203     *            scheme of the connection that requests authentication.
204     * @throws SecurityException
205     *             if a security manager denies the password authentication
206     *             permission.
207     */
208    public static synchronized PasswordAuthentication requestPasswordAuthentication(
209            String rHost, InetAddress rAddr, int rPort, String rProtocol,
210            String rPrompt, String rScheme) {
211        SecurityManager sm = System.getSecurityManager();
212        if (sm != null) {
213            sm.checkPermission(requestPasswordAuthenticationPermission);
214        }
215        if (thisAuthenticator == null) {
216            return null;
217        }
218        // set the requester info so it knows what it is requesting
219        // authentication for
220        thisAuthenticator.host = rHost;
221        thisAuthenticator.addr = rAddr;
222        thisAuthenticator.port = rPort;
223        thisAuthenticator.protocol = rProtocol;
224        thisAuthenticator.prompt = rPrompt;
225        thisAuthenticator.scheme = rScheme;
226        thisAuthenticator.rt = RequestorType.SERVER;
227
228        // returns the authentication info obtained by the registered
229        // Authenticator
230        return thisAuthenticator.getPasswordAuthentication();
231    }
232
233    /**
234     * Returns the host name of the connection that requests authentication or
235     * {@code null} if unknown.
236     *
237     * @return name of the requesting host or {@code null}.
238     */
239    protected final String getRequestingHost() {
240        return host;
241    }
242
243    /**
244     * If the permission check of the security manager does not result in a
245     * security exception, this method invokes the methods of the registered
246     * authenticator to get the authentication info.
247     *
248     * @return password authentication info or {@code null} if no authenticator
249     *         exists.
250     * @param rHost
251     *            host name of the connection that requests authentication.
252     * @param rAddr
253     *            address of the connection that requests authentication.
254     * @param rPort
255     *            port of the connection that requests authentication.
256     * @param rProtocol
257     *            protocol of the connection that requests authentication.
258     * @param rPrompt
259     *            realm of the connection that requests authentication.
260     * @param rScheme
261     *            scheme of the connection that requests authentication.
262     * @param rURL
263     *            url of the connection that requests authentication.
264     * @param reqType
265     *            requestor type of the connection that requests authentication.
266     * @throws SecurityException
267     *             if a security manager denies the password authentication
268     *             permission.
269     */
270    public static PasswordAuthentication requestPasswordAuthentication(
271            String rHost, InetAddress rAddr, int rPort, String rProtocol,
272            String rPrompt, String rScheme, URL rURL,
273            Authenticator.RequestorType reqType) {
274        SecurityManager sm = System.getSecurityManager();
275        if (null != sm) {
276            sm.checkPermission(requestPasswordAuthenticationPermission);
277        }
278        if (null == thisAuthenticator) {
279            return null;
280        }
281        // sets the requester info so it knows what it is requesting
282        // authentication for
283        thisAuthenticator.host = rHost;
284        thisAuthenticator.addr = rAddr;
285        thisAuthenticator.port = rPort;
286        thisAuthenticator.protocol = rProtocol;
287        thisAuthenticator.prompt = rPrompt;
288        thisAuthenticator.scheme = rScheme;
289        thisAuthenticator.url = rURL;
290        thisAuthenticator.rt = reqType;
291
292        // returns the authentication info obtained by the registered
293        // Authenticator
294        return thisAuthenticator.getPasswordAuthentication();
295
296    }
297
298    /**
299     * Returns the URL of the authentication request.
300     *
301     * @return authentication request url.
302     */
303    protected URL getRequestingURL() {
304        return url;
305    }
306
307    /**
308     * Returns the type of this request, it can be {@code PROXY} or {@code SERVER}.
309     *
310     * @return RequestorType of the authentication request.
311     */
312    protected Authenticator.RequestorType getRequestorType() {
313        return rt;
314    }
315
316    /**
317     * Enumeration class for the origin of the authentication request.
318     */
319    public enum RequestorType {
320
321        /**
322         * Type of proxy server
323         */
324        PROXY,
325
326        /**
327         * Type of origin server
328         */
329        SERVER
330    }
331}
332