/AuthenticRoast/AuthenticRoast-Impl/src/main/java/name/aikesommer/authenticator/AuthenticationRequestImpl.java

http://authenticroast.googlecode.com/ · Java · 544 lines · 354 code · 101 blank · 89 comment · 16 complexity · 5e236966d8648c4ae21445e9fdc0055f MD5 · raw file

  1. /**
  2. * Copyright (C) 2007-2010 Aike J Sommer (http://aikesommer.name/)
  3. *
  4. * This file is part of AuthenticRoast.
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General
  17. * Public License along with this library; if not, write to the
  18. * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  19. * Boston, MA 02110-1301 USA
  20. *
  21. * You can reach the author and get more information about this
  22. * project at: http://aikesommer.name/
  23. */
  24. package name.aikesommer.authenticator;
  25. import java.util.AbstractMap;
  26. import java.util.AbstractSet;
  27. import java.util.Enumeration;
  28. import java.util.Iterator;
  29. import java.util.Map;
  30. import java.util.Map.Entry;
  31. import java.util.Set;
  32. import javax.security.auth.Subject;
  33. import javax.servlet.ServletContext;
  34. import javax.servlet.http.HttpServletRequest;
  35. import javax.servlet.http.HttpServletResponse;
  36. import org.apache.catalina.connector.Request;
  37. import org.apache.catalina.connector.Response;
  38. /**
  39. * The class representing the request for authentication to be passed to the
  40. * authenticator-object in aur web-app. This basically encapsulates some
  41. * of the involved objects for simplicity.
  42. *
  43. * @author Aike J Sommer
  44. */
  45. public abstract class AuthenticationRequestImpl implements ModifiableRequest {
  46. private HttpServletResponse response;
  47. private HttpServletRequest request;
  48. private boolean mandatory;
  49. private boolean forwarded = false;
  50. private boolean crossContext;
  51. private Map<String, Object> authenticationMap;
  52. public AuthenticationRequestImpl(HttpServletRequest request, HttpServletResponse response,
  53. boolean mandatory, boolean crossContext) {
  54. this.request = request;
  55. this.response = response;
  56. this.mandatory = mandatory;
  57. this.crossContext = crossContext;
  58. this.authenticationMap = crossContext ? SuperSession.self(request, response, true).attributes()
  59. : getSessionMap();
  60. }
  61. protected abstract AuthenticationRequest delegate(ServletContext context);
  62. /**
  63. * Get the ServletContext for the current request.
  64. *
  65. * @return The ServletContext instance for the current request.
  66. */
  67. public ServletContext getServletContext() {
  68. return request.getSession(true).getServletContext();
  69. }
  70. /**
  71. * Get the HttpServletRequest for the current request.
  72. *
  73. * @return The HttpServletRequest instance for the current request.
  74. */
  75. public HttpServletRequest getHttpServletRequest() {
  76. return request;
  77. }
  78. /**
  79. * Get the HttpServletResponse for the current request.
  80. *
  81. * @return The HttpServletResponse instance for the current request.
  82. */
  83. public HttpServletResponse getHttpServletResponse() {
  84. return response;
  85. }
  86. /**
  87. * Get the HTTP-Parameter with given name.
  88. *
  89. * @param name The name of the parameter to return.
  90. * @return The value of the parameter.
  91. */
  92. public String getParameter(String name) {
  93. return request.getParameter(name);
  94. }
  95. /**
  96. * Get the request-path.
  97. * @return Get the complete path of the current request, starting after
  98. * the context-path and excluding any parameters.
  99. */
  100. public String getRequestPath() {
  101. String requested = request.getRequestURI();
  102. if (! requested.startsWith(getContextPath())) {
  103. throw new IllegalArgumentException(requested);
  104. }
  105. return requested.substring(getContextPath().length());
  106. }
  107. /**
  108. * Get the context-path.
  109. * @return The context-path for the current request.
  110. */
  111. public String getContextPath() {
  112. return request.getContextPath();
  113. }
  114. public boolean isForwarded() {
  115. return forwarded;
  116. }
  117. public void setForwarded(boolean forwarded) {
  118. this.forwarded = forwarded;
  119. }
  120. public boolean isCrossContext() {
  121. return crossContext;
  122. }
  123. public void setCrossContext(boolean b) {
  124. crossContext = b;
  125. }
  126. /**
  127. * Get a map containing all session attributes.
  128. * Changes to this map will be reflected in the session attributes.
  129. *
  130. * @return A map representing all session attributes.
  131. */
  132. public Map<String, Object> getSessionMap() {
  133. return new AttributeMap() {
  134. @Override
  135. public Enumeration<String> getAttributeNames() {
  136. return request.getSession(true).getAttributeNames();
  137. }
  138. @Override
  139. public Object getAttribute(String s) {
  140. return request.getSession(true).getAttribute(s);
  141. }
  142. @Override
  143. public void setAttribute(String s, Object o) {
  144. request.getSession(true).setAttribute(s, o);
  145. }
  146. @Override
  147. public void removeAttribute(String s) {
  148. request.getSession(true).removeAttribute(s);
  149. }
  150. };
  151. }
  152. /**
  153. * Get a map containing all request attributes.
  154. * Changes to this map will be reflected in the request attributes.
  155. *
  156. * @return A map representing all request attributes.
  157. */
  158. public Map<String, Object> getRequestMap() {
  159. return new AttributeMap() {
  160. @Override
  161. public Enumeration<String> getAttributeNames() {
  162. return request.getAttributeNames();
  163. }
  164. @Override
  165. public Object getAttribute(String s) {
  166. return request.getAttribute(s);
  167. }
  168. @Override
  169. public void setAttribute(String s, Object o) {
  170. request.setAttribute(s, o);
  171. }
  172. @Override
  173. public void removeAttribute(String s) {
  174. request.removeAttribute(s);
  175. }
  176. };
  177. }
  178. public Map<String, Object> getApplicationMap() {
  179. final ServletContext context = getServletContext();
  180. return new AttributeMap() {
  181. @Override
  182. public Enumeration<String> getAttributeNames() {
  183. return context.getAttributeNames();
  184. }
  185. @Override
  186. public Object getAttribute(String s) {
  187. return context.getAttribute(s);
  188. }
  189. @Override
  190. public void setAttribute(String s, Object o) {
  191. context.setAttribute(s, o);
  192. }
  193. @Override
  194. public void removeAttribute(String s) {
  195. context.removeAttribute(s);
  196. }
  197. };
  198. }
  199. public Map<String, Object> getAuthenticationMap() {
  200. return authenticationMap;
  201. }
  202. /**
  203. * Get whether authentication is mandatory for the current request.
  204. * If authentication is not mandatory the authenticator can still return
  205. * Success to signal that the resource should be served anyways.
  206. *
  207. * @return If authentication is mandatory for the requested resource.
  208. */
  209. public boolean isMandatory() {
  210. return mandatory;
  211. }
  212. /**
  213. * You dont need to call this and it should be hidden in an impl-class.
  214. *
  215. * @param mandatory
  216. */
  217. public void setMandatory(boolean mandatory) {
  218. this.mandatory = mandatory;
  219. }
  220. public ServletContext getOriginalContext() {
  221. return getServletContext();
  222. }
  223. public static class JSR196 extends AuthenticationRequestImpl implements JSR196Request {
  224. private Subject clientSubject;
  225. public JSR196(HttpServletRequest request, HttpServletResponse response,
  226. Subject clientSubject, boolean mandatory, boolean crossContext) {
  227. super(request, response, mandatory, crossContext);
  228. this.clientSubject = clientSubject;
  229. }
  230. /**
  231. * Get the ClientSubject for the current request.
  232. *
  233. * @return The ClientSubject instance for the current request.
  234. */
  235. public Subject getClientSubject() {
  236. return clientSubject;
  237. }
  238. @Override
  239. protected JSR196Request delegate(ServletContext context) {
  240. return new WrappedRequest.JSR196(context, this);
  241. }
  242. }
  243. public static class Tomcat6 extends AuthenticationRequestImpl implements Tomcat6Request {
  244. private Request catalinaRequest;
  245. private Response catalinaResponse;
  246. public Tomcat6(Request request, Response response, boolean mandatory, boolean crossContext) {
  247. super(request.getRequest(), response.getResponse(), mandatory, crossContext);
  248. this.catalinaRequest = request;
  249. this.catalinaResponse = response;
  250. }
  251. public Request getCatalinaRequest() {
  252. return catalinaRequest;
  253. }
  254. public Response getCatalinaResponse() {
  255. return catalinaResponse;
  256. }
  257. @Override
  258. protected Tomcat6Request delegate(ServletContext context) {
  259. return new WrappedRequest.Tomcat6(context, this);
  260. }
  261. }
  262. public abstract static class AttributeMap extends NoteMap {
  263. @Override
  264. public Iterator<String> getNoteNames() {
  265. return new Iterator<String>() {
  266. Enumeration<String> pos = getAttributeNames();
  267. String current = null;
  268. String last = null;
  269. public boolean hasNext() {
  270. return pos.hasMoreElements();
  271. }
  272. public String next() {
  273. last = current;
  274. current = pos.nextElement();
  275. return current;
  276. }
  277. public void remove() {
  278. if (current == null) {
  279. return;
  280. }
  281. String before = last;
  282. removeAttribute(current);
  283. if (before != null) {
  284. while (hasNext() && !before.equals(next())) {
  285. }
  286. }
  287. }
  288. };
  289. }
  290. @Override
  291. public Object getNote(String s) {
  292. return getAttribute(s);
  293. }
  294. @Override
  295. public void setNote(String s, Object o) {
  296. setAttribute(s, o);
  297. }
  298. @Override
  299. public void removeNote(String s) {
  300. removeAttribute(s);
  301. }
  302. public abstract Enumeration<String> getAttributeNames();
  303. public abstract Object getAttribute(String s);
  304. public abstract void setAttribute(String s, Object o);
  305. public abstract void removeAttribute(String s);
  306. }
  307. public abstract static class NoteMap extends AbstractMap<String, Object> {
  308. public abstract Iterator<String> getNoteNames();
  309. public abstract Object getNote(String s);
  310. public abstract void setNote(String s, Object o);
  311. public abstract void removeNote(String s);
  312. @Override
  313. public Set<Entry<String, Object>> entrySet() {
  314. return new NoteEntrySet(this);
  315. }
  316. @Override
  317. public int size() {
  318. int count = 0;
  319. for (Iterator<String> it = getNoteNames(); it.hasNext();) {
  320. it.next();
  321. count++;
  322. }
  323. return count;
  324. }
  325. @Override
  326. public Object get(Object key) {
  327. if (!(key instanceof String)) {
  328. return null;
  329. }
  330. return getNote((String) key);
  331. }
  332. @Override
  333. public boolean containsKey(Object key) {
  334. if (!(key instanceof String)) {
  335. return false;
  336. }
  337. String keyStr = (String) key;
  338. if (get(keyStr) != null) {
  339. return true;
  340. }
  341. for (Iterator<String> it = getNoteNames(); it.hasNext();) {
  342. String name = it.next();
  343. if (name.equals(keyStr)) {
  344. return true;
  345. }
  346. }
  347. return false;
  348. }
  349. @Override
  350. public boolean isEmpty() {
  351. return !getNoteNames().hasNext();
  352. }
  353. @Override
  354. public Set<String> keySet() {
  355. return new NoteKeySet(this);
  356. }
  357. @Override
  358. public void clear() {
  359. for (Iterator<String> it = keySet().iterator(); it.hasNext();) {
  360. it.remove();
  361. }
  362. }
  363. @Override
  364. public Object put(String key, Object value) {
  365. Object old = get(key);
  366. setNote(key, value);
  367. return old;
  368. }
  369. @Override
  370. public Object remove(Object key) {
  371. if (!(key instanceof String)) {
  372. return null;
  373. }
  374. String keyStr = (String) key;
  375. Object old = get(keyStr);
  376. removeNote(keyStr);
  377. return old;
  378. }
  379. }
  380. public static class NoteKeySet extends AbstractSet<String> {
  381. private NoteMap map;
  382. public NoteKeySet(NoteMap map) {
  383. this.map = map;
  384. }
  385. @Override
  386. public Iterator<String> iterator() {
  387. return new Iterator<String>() {
  388. private String current = null;
  389. private Iterator<String> pos = map.getNoteNames();
  390. public boolean hasNext() {
  391. return pos.hasNext();
  392. }
  393. public String next() {
  394. current = pos.next();
  395. return current;
  396. }
  397. public void remove() {
  398. pos.remove();
  399. }
  400. };
  401. }
  402. @Override
  403. public int size() {
  404. return map.size();
  405. }
  406. }
  407. public static class NoteEntrySet extends AbstractSet<Map.Entry<String, Object>> {
  408. private NoteMap map;
  409. public NoteEntrySet(NoteMap map) {
  410. this.map = map;
  411. }
  412. @Override
  413. public Iterator<Map.Entry<String, Object>> iterator() {
  414. return new Iterator<Map.Entry<String, Object>>() {
  415. private Iterator<String> it = map.keySet().iterator();
  416. public boolean hasNext() {
  417. return it.hasNext();
  418. }
  419. public Map.Entry<String, Object> next() {
  420. return new Map.Entry() {
  421. private String key = it.next();
  422. public Object getKey() {
  423. return key;
  424. }
  425. public Object getValue() {
  426. return map.get(key);
  427. }
  428. public Object setValue(Object value) {
  429. return map.put(key, value);
  430. }
  431. };
  432. }
  433. public void remove() {
  434. it.remove();
  435. }
  436. };
  437. }
  438. @Override
  439. public int size() {
  440. return map.size();
  441. }
  442. }
  443. }