Skip to content

Instantly share code, notes, and snippets.

@novoj
Created February 2, 2015 19:51
Show Gist options
  • Save novoj/5f09bdc1164fbca77c21 to your computer and use it in GitHub Desktop.
Save novoj/5f09bdc1164fbca77c21 to your computer and use it in GitHub Desktop.
Quiz:
Try to replace request.getRequestURI() in #commence method with custom value retrieved from request attribute:
org.springframework.security.web.access.channel.RetryWithHttpsEntryPoint
org.springframework.security.web.access.channel.RetryWithHttpEntryPoint
Try to override org.springframework.security.web.DefaultRedirectStrategy, but reuse complex logic in org.springframework.security.web.DefaultRedirectStrategy#calculateRedirectUrl
@rwinch
Copy link

rwinch commented Feb 3, 2015

This is a discussion based on twitter

Try to replace request.getRequestURI() in #commence method with custom value retrieved from request attribute:
org.springframework.security.web.access.channel.RetryWithHttpsEntryPoint
org.springframework.security.web.access.channel.RetryWithHttpEntryPoint

A framework will never provide every feature, but it should enable you to do anything that is reasonable. Customization is not always about using existing code. You can create a custom ChannelEntryPoint that does this with only a few lines of code. For example:

public class CustomChannelEntryPointImpl implements ChannelEntryPoint {
    private final RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

    public void commence(HttpServletRequest request, HttpServletResponse response) 
      throws IOException, ServletException {
        String redirectUrl = (String) request.getAttribute("someAttr");

        redirectStrategy.sendRedirect(request, response, redirectUrl);
    }
}

Try to override org.springframework.security.web.DefaultRedirectStrategy, but reuse complex logic in org.springframework.security.web.DefaultRedirectStrategy#calculateRedirectUrl

What exactly are you wanting to do?

@novoj
Copy link
Author

novoj commented Feb 4, 2015

I know that I could implement my own implementation of the interface if neccessary. Interfaces are well designed.

But my aim is not to replace default implementation that is battle tested on many installations and patched by community. I just want to alter existing logic slightly to serve my purpose (my exceptional case if you will) and everything else left in place as it is.

This approach have served me well since year 2007 when I started with Acegi Security (I believe there are still some working tweaks in code that I made several years ago).

So unlocking some properties to protected mode, or spliting complex methods to several smaller ones with protected access would help a lot in this case.

When I work with (and need to extend) Spring Framework - core, there are usually ways how to hack-in relatively easily.

Btw. my solution to Entry points was:

public class UrlRewriteAwareRetryWithHttpEntryPoint extends RetryWithHttpEntryPoint {
    private static final Log log = LogFactory.getLog(UrlRewriteAwareRetryWithHttpsEntryPoint.class);
    private static String REWRITTEN_ATTR_NAME = "REWRITE_WAS_REWRITTEN";
    private static String REWRITTEN_URI_ATTR_NAME = "REWRITE_ORIGINAL_REQUEST_URI";

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        if (REWRITTEN_ATTR_NAME == null) {
            super.commence(request, response);
        } else {
            final Object attr = request.getAttribute(REWRITTEN_ATTR_NAME);
            Boolean wasRewritten = attr == null ? null : Boolean.valueOf(attr.toString());
            if (wasRewritten != null && wasRewritten) {
                final String uri = (String)request.getAttribute(REWRITTEN_URI_ATTR_NAME);
                super.commence(new RediretUriHttpServletRequestWrapper(request, uri), response);
            } else {
                super.commence(request, response);
            }
        }
    }

}

@rwinch
Copy link

rwinch commented Feb 4, 2015

Remember proper encapsulation is important to keep code complexity down to a minimum. In general, Spring Security favors composition over inheritance. For this reason, you will not find a lot of hooks via protected methods. This is especially true in implementations of interfaces with only a single method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment