📄 loginservlet.java
字号:
/* -*- mode:java; indent-tabs-mode:nil; c-basic-offset:2 -*- * * $RCSFile$ $Revision: 1.22 $ $Date: 2006/01/25 16:56:19 $ * * Copyright (c) 2003 Autonomy Corp. All Rights Reserved. * Permission to use, copy, modify, and distribute this file is hereby * granted without fee, provided that the above copyright notice appear * in all copies. */import java.io.*;import java.net.*;import java.util.*;import javax.servlet.*;import javax.servlet.http.*;import com.ultraseek.xpa.search.*;/** * This Servlet demonstrates how to specialize the behavior of * the standard SearchServlet to provide filtering of results * that require login to specific sites. * <p> * This servlet requires version 2.3 of the servlet specification. * * @author Ultraseek Engineering * @version 2.1 * @since XPA2.1 * @requires Servlet 2.3 * @serial exclude */public class LoginServlet extends SearchServlet{ /** * LoginServlet requires Servlet version 2.3. */ protected static final int REQUIRED_SERVLET_VERSION_MAJOR = 2; protected static final int REQUIRED_SERVLET_VERSION_MINOR = 3; public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException { try { if (req.getParameter("login")!=null) doLoginForm(req,resp); else { SearchRequest sr = new LoginSearchRequest(req,resp); sr.handle(); } } catch (ServletException e) { DEBUG(resp,e); throw e; } catch (Exception e) { DEBUG(resp,e); throw new ServletException(e.getLocalizedMessage(),e); } } // Names for session-persistent attributes static final protected String myName = LoginServlet.class.getName(); static final protected String GUARD_ATTRIBUTE = myName + ".guard"; static final protected String FILTERED_SITES_ATTRIBUTE = myName + ".filteredSites"; static final protected String GUESSES_ATTRIBUTE = myName + ".guesses"; static final protected String LOGINS_ATTRIBUTE = myName + ".logins"; static final protected String PRIORQUERY_ATTRIBUTE = myName + ".priorQuery"; protected class LoginSearchRequest extends SearchRequest { LoginSearchRequest(HttpServletRequest req, HttpServletResponse resp) throws IOException { super(req,resp); } /* The following objects are session-persistent */ AccessGuard guard; // Access Guard for the session Set filteredSites; // sites for which we've removed results Map logins; // Already established logins Set guesses; // user:password combinations to guess with StringBuffer priorQuery; // previous query in this session /** * After parsing query parameters, ensure that a session ID * has been created for each session. * Lookup the session persistent Objects and set local * references to them. */ protected void parseQueryParameters() throws IOException, ServletException { super.parseQueryParameters(); if (session==null) { session = req.getSession(true); } if (session.getAttribute(GUARD_ATTRIBUTE)==null) { // Synchronized as background threads from the guard modify them. filteredSites = Collections.synchronizedSet(new HashSet()); guesses = Collections.synchronizedSet(new HashSet()); logins = Collections.synchronizedMap(new HashMap()); guard = new GuessingAccessGuard(guesses,filteredSites); session.setAttribute(FILTERED_SITES_ATTRIBUTE, filteredSites); session.setAttribute(GUESSES_ATTRIBUTE, guesses); session.setAttribute(LOGINS_ATTRIBUTE, logins); session.setAttribute(GUARD_ATTRIBUTE, guard); session.setAttribute(PRIORQUERY_ATTRIBUTE, new StringBuffer(256)); } guard = (AccessGuard) session.getAttribute(GUARD_ATTRIBUTE); filteredSites = (Set) session.getAttribute(FILTERED_SITES_ATTRIBUTE); guesses = (Set) session.getAttribute(GUESSES_ATTRIBUTE); logins = (Map) session.getAttribute(LOGINS_ATTRIBUTE); priorQuery = (StringBuffer) session.getAttribute(PRIORQUERY_ATTRIBUTE); } /** * Whenever the user generates a new query in a session, we must * erase the list of "password protected sites" - as we will obtain * new sites for the new query. */ protected String makeQueryText() throws IOException { String newText = super.makeQueryText(); if (newText == null || !newText.equals(priorQuery.toString())) { // We have new query text. We must clear out the sites // that "have password protected results" as we have new results. filteredSites.clear(); priorQuery.delete(0,priorQuery.length()); if (newText!=null) priorQuery.append(newText); } return newText; } /** * Checking security on results can take some time, so * give the user feedback by flushing * the output buffer more frequently. */ protected void showRelatedTopics() throws IOException, ServletException { super.showRelatedTopics(); out.flush(); } protected void showResult(SearchResult sr) throws IOException { super.showResult(sr); out.flush(); } /** * Keep a list of the sites that were filtered due to a Login requirement. * The list of filtered Sites will persist for the duration of the query, * and may grow as additional SearchResults are checked before * display. * <p> * The list of filtered Sites is also modified by the GuessingAccessGuard * for this session. */ protected void handleSecurityException(SecurityException e) { if (e instanceof LoginRequiredException) { filteredSites.add((LoginRequiredException) e); } } /** * After the search result bottom nav bar, show the list of sites * that had results protected by password. */ protected void showFootnotes() throws IOException, ServletException { // Show login footnotes for password-protected results. showFilteredSites(); } /** * Display the sites which have filtered results, with a * link to our Login screen. */ private void showFilteredSites() throws MalformedURLException { if (filteredSites == null || filteredSites.isEmpty()) return; DEBUG(out,"showFilteredSites"); Iterator it = filteredSites.iterator(); while (it.hasNext()) { Object o = it.next(); if (!(o instanceof LoginRequiredException)) continue; LoginRequiredException e = (LoginRequiredException) o; String protocol = e.getProtocol(); String host = e.getHost(); int port = e.getPort(); String realm = e.getRealm(); String site = new URL(protocol,host,port,"/").toString(); StringBuffer sb = new StringBuffer(256); sb.append(req.getRequestURI()); sb.append("?login=1"); sb.append("&protocol="); sb.append(encode_URL(protocol)); sb.append("&host="); sb.append(encode_URL(host)); sb.append("&port="); sb.append(Integer.toString(port)); sb.append("&realm="); sb.append(encode_URL(realm)); sb.append("&searchable="); sb.append(encode_URL(col)); Enumeration enumeration = req.getParameterNames(); while (enumeration.hasMoreElements()) { String name = (String)enumeration.nextElement(); String[] values = req.getParameterValues(name); for (int i=0; i<values.length; i++) { String value = values[i]; sb.append('&'); sb.append(encode_URL(name)); sb.append('='); sb.append(encode_URL(value)); } } out.println("<p>"); out.print(text(textMap,"Password-protected results from")); out.print(" <a href=\""); printHTMLEncoded(out,site); out.print("\">"); printHTMLEncoded(out,site); out.println("</a> "); out.print(text(textMap,"are available.")); out.println("<br>"); out.print("<a href=\""); printHTMLEncoded(out,sb.toString()); out.print("\">"); out.print(text(textMap,"Login")); out.print("</a> "); out.print(text(textMap,"to the realm")); out.print(" \""); printHTMLEncoded(out,realm); out.print("\" "); out.println(text(textMap,"to include them.")); } DEBUG(out,"/showFilteredSites"); } /** * Apply the session specific guard to the search source. * Then let our parent apply any requested date sorting, title sorting, * or Location Grouping. */ protected Searchable addSearchableProcessing(Searchable searchable) { DEBUG(out,"LoginServlet.addSearchableProcessing"); searchable = new GuardingSearchable( searchable, guard ); return super.addSearchableProcessing(searchable); } } // class SearchRequest /** * An demonstration <code>AccessGuard</code> * which accepts any non-empty username/password combination. * <p> * This <code>AccessGuard</code> does not try to guess passwords. * If correct input is given, the site / user:password pairing * is added to the <code>AccessGuard</code>'s authorization list. */ protected class AllowAnyoneAccessGuard extends AccessGuard // Change to RandomAccessGuard for testing { private Set guesses; private Set filteredSites; public AllowAnyoneAccessGuard(Set guesses, Set filteredSites) { super(); if ((guesses==null) || (filteredSites==null)) throw new IllegalArgumentException("null set not allowed"); this.guesses = guesses; this.filteredSites = filteredSites; } public void checkGuardUncached(Object o) throws SecurityException { if (o==null || !(o instanceof SearchResult)) return; SearchResult sr = (SearchResult) o; try { if (!sr.getURL().getProtocol().toLowerCase().startsWith("http")) throw new SecurityException( this.getClass().getName() + ": " + o.toString() );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -