Results 1 to 5 of 5

Thread: Context-relative redirect from within Interceptor?

  1. #1

    Default Context-relative redirect from within Interceptor?

    Hi everyone,

    I have the following requirement: if a user access the page three times within the same session, send them back to the home page, and disable further access for this session.

    I have implemented this login in an interceptor:

    Code:
    public class ThreeStrikesAndYrOutInterceptor extends HandlerInterceptorAdapter {
    	private static final Log logger = LogFactory.getLog(ThreeStrikesAndYrOutInterceptor.class);
    	private static final String N_STRIKES = "N_STRIKES";
    	
    	private String redirect;
    
    	private int incrementStrikes(HttpServletRequest request) {
    		Integer strikesAsInteger = (Integer) WebUtils.getSessionAttribute(request, N_STRIKES);
    		if (strikesAsInteger == null) {
    			strikesAsInteger = new Integer(0);	
    		} else {
    			strikesAsInteger = new Integer(strikesAsInteger.intValue() + 1);
    		}
    		WebUtils.setSessionAttribute(request, N_STRIKES, strikesAsInteger);
    		return strikesAsInteger.intValue();
    	}
    	
    	@Override
    	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    		int strikes = incrementStrikes(request);
    		logger.debug("strike count? " + strikes);
    		if (strikes < 3) {
    			return true;
    		}
    		logger.warn("Detected three accesses in one session - disallowing further requests!");
    		response.sendRedirect(redirect);
    		return false;
    	}
    
    	public void setRedirect(String redirect) {
    		this.redirect = redirect;
    	}
    }
    If i set redirect like this:

    Code:
    <bean name="threeStrikesAndYrOutInterceptor" class="com.equifax.imover.interceptor.ThreeStrikesAndYrOutInterceptor">
        <property name="redirect" value="/overview.do" />
    </bean>
    it redirects me to http://myserver/overview.do which does NOT exist!

    How can I tell it to redirect context-sensitive without hardcoding the path??

    Thank you!

  2. #2

    Default

    Just as a guess - what do you get if you don't specify a path:
    Code:
    <bean name="threeStrikesAndYrOutInterceptor" class="com.equifax.imover.interceptor.ThreeStrikesAndYrOutInterceptor">
        <property name="redirect" value="overview.do" />
    </bean>
    I would expect it to be relative to the local pages. ie in your servlet.

  3. #3
    Join Date
    May 2005
    Location
    California, US
    Posts
    735

    Default

    Here's what I did, which I was not happy with:
    Code:
        @Override
        public boolean preHandle(final HttpServletRequest request,
                final HttpServletResponse response,
                final Object handler) {
    
            if (log.isDebugEnabled())
                requestDebug(request);
    
            if (log.isDebugEnabled())
                servletDebug();
    
            if (request.getServletPath().compareTo("/start.zug") == 0)
                return (true);
    
            if (userPermissions.isAdmin())
                return (true);
    
            if (systemStatus.isSystemDown()) {
                try {
                    response.sendRedirect(serviceUrl(request, systemStatus
                            .getSystemDownView()));
                }
                catch (final IOException e) {
                    log.error("exception: {}", e);
                }
    
                return (false);
            }
    
            return (true);
        }
    
        private String serviceUrl(final HttpServletRequest request,
                final String page) {
            final StringBuilder sb = new StringBuilder();
    
            sb.append(request.getScheme());
            sb.append("://");
            sb.append(request.getServerName());
    
            final int port = request.getServerPort();
    
            if (port != 80) {
                sb.append(":");
                sb.append(port);
            }
    
            sb.append("/");
            sb.append(request.getContextPath());
    
            sb.append("/");
            sb.append(page);
    
            return (sb.toString());
        }
    
        private void requestDebug(final HttpServletRequest request) {
            log.debug("contextPath: {}", request.getContextPath());
            log.debug("pathInfo: {}", request.getPathInfo());
            log.debug("pathTranslated: {}", request.getPathTranslated());
            log.debug("requestUrl: {}", request.getRequestURL());
            log.debug("requestUri: {}", request.getRequestURI());
            log.debug("servletPath: {}", request.getServletPath());
            log.debug("serverName: {}", request.getServerName());
            log.debug("serverPort: {}", request.getServerPort());
            log.debug("protocol: {}", request.getProtocol());
            log.debug("scheme: {}", request.getScheme());
        }
    The method serviceUrl constructs the url to redirect to. The method systemDownView is incorrectly named; it should be systemDownFile since it's returning a file name, systemDown.jsp, not a view name. When deployed the file systemDown.jsp is in the root of the webapps/<myApp>/ directory along with the index.jsp start file.

    And apparently there are security issues with using the host name that's in the HttpServletRequest object; I think it's supplied by the client (browser or nefarious hacker, as the case may be).

  4. #4

    Default

    lumpynose, not sure if I understand 100%, but respone.sendRedirect() will work with relative redirects e.g. /mypage.jsp provided you give it a context path (no need to do the host/port portion)...

    In my case I solved this issue like so... and I believe you could simplify your serviceUrl method as well:

    Code:
    //turns /mypage.jsp into something like /myapp/mypage.jsp
    private String createRedirectUrl(HttpServletRequest request) {
    	if (redirect.startsWith("/")) {
    		return request.getContextPath() + redirect;
    	} else {
    		return redirect;
    	}
    }
    ...
    	
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    	...
    	logger.warn("Detected three accesses in one session - disallowing further requests!");
    	String redirect = createRedirectUrl(request);
    	logger.debug("Redirecting to " + redirect);
    	response.sendRedirect(redirect);
    	return false;
    }

  5. #5
    Join Date
    May 2005
    Location
    California, US
    Posts
    735

    Default

    Excellent; thanks!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •