1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 package org.apache.commons.httpclient.server;
32
33 import java.io.IOException;
34
35 import org.apache.commons.httpclient.Credentials;
36 import org.apache.commons.httpclient.Header;
37 import org.apache.commons.httpclient.HttpStatus;
38 import org.apache.commons.httpclient.UsernamePasswordCredentials;
39 import org.apache.commons.httpclient.auth.BasicScheme;
40
41 /***
42 * This request handler guards access to the http server when used in a request handler
43 * chain. It checks the headers for valid credentials and performs the
44 * authentication handshake if necessary.
45 *
46 * @author Ortwin Glueck
47 * @author Oleg Kalnichevski
48 */
49 public class AuthRequestHandler implements HttpRequestHandler {
50
51 private Credentials credentials = null;
52 private String realm = null;
53 private boolean keepalive = true;
54
55 /***
56 * The authenticate response header.
57 */
58 public static final String AUTH_RESP = "Authorization";
59
60 /***
61 * TODO replace creds parameter with a class specific to an auth scheme
62 * encapsulating all required information for a specific scheme
63 *
64 * @param creds
65 */
66 public AuthRequestHandler(final Credentials creds, final String realm, boolean keepalive) {
67 if (creds == null)
68 throw new IllegalArgumentException("Credentials may not be null");
69 this.credentials = creds;
70 this.keepalive = keepalive;
71 if (realm != null) {
72 this.realm = realm;
73 } else {
74 this.realm = "test";
75 }
76 }
77
78 public AuthRequestHandler(final Credentials creds, final String realm) {
79 this(creds, realm, true);
80 }
81
82 public AuthRequestHandler(final Credentials creds) {
83 this(creds, null, true);
84 }
85
86 public boolean processRequest(
87 final SimpleHttpServerConnection conn,
88 final SimpleRequest request) throws IOException
89 {
90 Header clientAuth = request.getFirstHeader(AUTH_RESP);
91 if (clientAuth != null && checkAuthorization(clientAuth)) {
92 return false;
93 } else {
94 SimpleResponse response = performBasicHandshake(conn, request);
95
96 request.getBodyBytes();
97 conn.writeResponse(response);
98 return true;
99 }
100 }
101
102
103 private SimpleResponse performBasicHandshake(
104 final SimpleHttpServerConnection conn,
105 final SimpleRequest request) throws IOException
106 {
107 SimpleResponse response = new SimpleResponse();
108 response.setStatusLine(
109 request.getRequestLine().getHttpVersion(),
110 HttpStatus.SC_UNAUTHORIZED);
111 if (!request.getRequestLine().getMethod().equalsIgnoreCase("HEAD")) {
112 response.setBodyString("unauthorized");
113 }
114 response.addHeader(new Header("WWW-Authenticate", "basic realm=\"" + this.realm + "\""));
115 if (this.keepalive) {
116 response.addHeader(new Header("Connection", "keep-alive"));
117 conn.setKeepAlive(true);
118 } else {
119 response.addHeader(new Header("Connection", "close"));
120 conn.setKeepAlive(false);
121 }
122 return response;
123 }
124
125 /***
126 * Checks if the credentials provided by the client match the required
127 * credentials
128 *
129 * @return true if the client is authorized, false if not.
130 * @param clientAuth
131 */
132 private boolean checkAuthorization(final Header clientAuth) {
133 String expectedAuthString = BasicScheme.authenticate(
134 (UsernamePasswordCredentials)credentials,
135 "ISO-8859-1");
136 return expectedAuthString.equals(clientAuth.getValue());
137 }
138
139 }