简体   繁体   English

在loadUserDetails方法中捕获httpServeletRequest

[英]Catch httpServeletRequest in loadUserDetails method

I have a customized spring AuthenticationProvider class but try to intercept the HTTPServletRequest and HTTPServletResponse within the loadUserDetails method. 我有一个自定义的spring AuthenticationProvider类,但是尝试在loadUserDetails方法中拦截HTTPServletRequestHTTPServletResponse

@Component("darnGoodAuthenticaionProvider")
public class DarnGoodAuthenticaionProvider 
                    extends HandlerInterceptorAdapter 
                    implements AuthenticationUserDetailsService {
    private HttpServletRequest request;
    private HttpServletResponse response;

    @Override
    public boolean preHandle(HttpServletRequest request, 
                            HttpServletResponse response, Object handler) 
                            throws Exception {
            this.request = request;
            this.response = response;
            // we don't want anything falling here
            return true;
}

    @Override
    public UserDetails loadUserDetails(Authentication token)throws 
                                                    UsernameNotFoundException{
           .......
    }
}

I know the preHandler method from HandlerIntercepterAdapter is capable to the job but how can I be sure that the preHandler method is called prior to loadUserDetails , so that I can get the request and response prepared? 我知道HandlerIntercepterAdapterpreHandler方法可以胜任这项工作,但是如何确保在loadUserDetails之前调用preHandler方法,以便可以准备请求和响应?

Thanks 谢谢

On a servlet container, each request will be handled from the moment the request is received until the response is returned by only one thread (request == current thread). 在servlet容器上,从接收请求的那一刻起,直到只有一个线程返回响应(请求==当前线程),每个请求都将得到处理。

So it's a matter of putting a servlet filter BEFORE the spring security filter chain (with the filter-mapping element above the filter-mapping of spring security), and storing the request and response in the thread using a ThreadLocal variable - see also this answer . 因此,需要将一个servlet过滤器放在spring安全过滤器链之前(spring-security安全过滤器映射上方的filter-mapping元素),然后使用ThreadLocal变量将请求和响应存储在线程中-另请参见此答案

Then on the DarnGoodAuthenticaionProvider access the request using a static method RequestResponseHolder.getRequest() . 然后在DarnGoodAuthenticaionProvider使用静态方法RequestResponseHolder.getRequest()访问请求。

web.xml config: web.xml配置:

<filter>
    <filter-name>saveRequestResponseFilter</filter-name>
    <filter-class>sample.save.request.filter.SaveRequestResponseFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>saveRequestResponseFilter</filter-name>
    <url-pattern>/mobilews/*</url-pattern>
</filter-mapping>

Filter to save the request response in the thread: 过滤以将请求响应保存在线程中:

public class SaveRequestResponseFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;

        RequestResponseHolder.setRequestResponse(req,resp);
        try {
            chain.doFilter(request, response);
        }
        finally {
            RequestResponseHolder.clear();
        }
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        ...
    }

    @Override
    public void destroy() {
       ...
    }
}

Request/Response holder: 请求/响应持有者:

public class RequestResponseHolder {

    private static ThreadLocal<HttpServletRequest> requestHolder = new ThreadLocal<HttpServletRequest>();
    private static ThreadLocal<HttpServletResponse> responseHolder = new ThreadLocal<HttpServletResponse>();


    public static void setRequestResponse(HttpServletRequest request, HttpServletResponse response) {
        requestHolder.set(request);
        responseHolder.set(response);
    }

    public static HttpServletRequest getServletRequest(){
         return requestHolder.get();
    }

    public static HttpServletResponse getServletResponse()  {
        return responseHolder.get();
    }

    public static void clear() {
        requestHolder.remove();
        responseHolder.remove();
    }
}

Obtaining the request from DarnGoodAuthenticaionProvider : DarnGoodAuthenticaionProvider获得请求:

HttpServletRequest req = RequestResponseHolder.getServletRequest();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM