Announcement Announcement Module
Collapse
No announcement yet.
multiple authentication providers and url rewriting Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • multiple authentication providers and url rewriting

    Hello, can somebody please explain how is it possible to use Spring Security in order to secure RESTful application using

    - api key, provided as part of the URL
    - basic HTTP auth
    - username and encrypted password in request headers

    so for example single REST provider with url like

    http://domain.com/rest/1.0/service/param1/param2/param3

    can be accessed as

    http://domain.com/rest/1.0/some-api-key-here/service

    without the need to explicitly map service to url,containing API key, as well as use URL without API key but secured with HTTP auth/custom headers

    I can think about providing the servlet filter, which may handle URL and put something into ThreadLocal to be picked up later by security provider, but this seems to be not consistent.

    Ideally I would like to provide set of authentication providers, which will handle different authentication scheme and probably rewrite URLs if required.

  • #2
    just refer Spring Security reference doc, it provide what you are looking for. Also its Filter base security,

    Comment


    • #3
      I created simple filter:

      Code:
      import org.springframework.http.client.support.HttpRequestWrapper;
      import org.springframework.security.core.context.SecurityContextHolder;
      import org.springframework.web.filter.GenericFilterBean;
      
      import javax.servlet.*;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletRequestWrapper;
      import java.io.IOException;
      import java.util.regex.Matcher;
      import java.util.regex.Pattern;
      
      public class APIKeyFilter extends GenericFilterBean{
      
          private final Pattern pattern;
      
          public APIKeyFilter(String urlPattern) {
              pattern = Pattern.compile(urlPattern);
      
          }
      
          @Override
          public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                  throws IOException, ServletException {
              HttpServletRequest servletRequest = (HttpServletRequest) request;
              final String requestPath = servletRequest.getPathInfo();
              Matcher matcher = pattern.matcher(requestPath);
              if (matcher.find()) {
                  String apiKey = matcher.group(1);
                  SecurityContextHolder.getContext().setAuthentication(new APIKey(apiKey));
                  final int end = matcher.end(1);
                  request = new HttpServletRequestWrapper(servletRequest) {
                      @Override
                      public String getPathInfo() {
                          String s = requestPath.substring(end);
                          return s;
                      }
                  };
              }
              chain.doFilter(request,response);
          }
      
      }
      and injected it into Spring configuration:

      Code:
          
          <bean name="apiKeyFilter" class="APIKeyFilter">
              <constructor-arg value="^/([^\\/]+)/service/"/>
          </bean>
      
      
      
          <security:http auto-config='true'>
              <security:http-basic/>
              <security:custom-filter ref="apiKeyFilter" before="BASIC_AUTH_FILTER"/>
              <security:intercept-url pattern="/**/service/**" access="ROLE_CUSTOMER"/>
          </security:http>
      At this point filter is called and request is replaced with new one, but later on I am getting 404 error because there is no such URL. What may be wrong here? The url supposed to be replaced with new one (and the one without additional api key is working for sure)

      Comment


      • #4
        I solved the problem with overriding getRequestURI and getRequestUrl methods. Apache CXF servlet uses those methods in order to resolve URL mappings, so it wasn't Spring issue.

        Comment

        Working...
        X