以编程方式在过滤器中的Spring Security中登录用户

时间:2014-05-21 12:37:44

标签: java spring spring-security servlet-filters

我正在尝试实施过滤器,以便根据特定条件以编程方式登录用户。

这是我的过滤方法:

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) servletRequest;
    HttpServletResponse response = (HttpServletResponse) servletResponse;
    Cookie[] cookies = request.getCookies();

    boolean typo3loggedin = true;
    String memberNo = "100003";

    HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request, response);
    SecurityContext securityContext = contextRepository.loadContext(holder);
    Authentication authentication = securityContext.getAuthentication();


    if (cookies != null && cookies.length > 0 ) {
        for (int i = 0; i < cookies.length; i++) {
            String name = cookies[i].getName();
            String value = cookies[i].getValue();
            if (name.equalsIgnoreCase("fe_typo_user")) typo3loggedin = true; //
            logger.debug(String.format("cookie-name: %s, cookie-value: %s", name, value));
        }
    }

    if (typo3loggedin && (authentication == null || !authentication.isAuthenticated())) {
        List<GrantedAuthority> grantedAuths = new ArrayList<GrantedAuthority>();
        grantedAuths.add(new SimpleGrantedAuthority("ROLE_USER"));
        if (authentication == null ) authentication = new UsernamePasswordAuthenticationToken(memberNo, "", grantedAuths);
        securityContext.setAuthentication(authentication);
        contextRepository.saveContext(securityContext, request, response);
        logger.debug("Logged-in from typo3 as user " + memberNo);
    }

    filterChain.doFilter(servletRequest, servletResponse);
}

但每当我尝试保存身份验证时,都会收到以下错误:

    java.lang.ClassCastException: org.mortbay.jetty.Response cannot be cast to org.springframework.security.web.context.SaveContextOnUpdateOrErrorResponseWrapper
            at org.springframework.security.web.context.HttpSessionSecurityContextRepository.saveContext(HttpSessionSecurityContextRepository.java:108)
            at com.scaratec.bueroprint.mdb.ui.server.filter.SsoFilter.doFilter(SsoFilter.java:74)
            at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:343)
            at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:260)
            at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1212)
            at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:233)
            at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
            at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1212)
            at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
            at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
            at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1212)
            at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:399)
            at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
            at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
            at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:766)
            at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:450)
            at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230)
            at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
            at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
            at org.mortbay.jetty.Server.handle(Server.java:326)
            at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
            at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:928)
            at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:549)
            at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
            at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
            at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:410)
            at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)

由于org.mortbay.jetty.Response实现了HttpServletResponse作为saveContext()的参数,因此异常消息本身对我没有任何意义。

更新:正如下面的评论中所建议的那样,我已经扩展了AbstractPreAuthenticatedProcessingFilter,这是针对这种情况而做的。这完全解决了我的问题。

1 个答案:

答案 0 :(得分:2)

它看起来像一个简单的类转换问题。请求对象不是SaveContextOnUpdateOrErrorResponseWrapper的实例。此类用于在请求通过Spring Security过滤器链时包装请求 - 它由SecurityContextPersistenceFilter创建。

看起来对SecurityContextRepository的调用来自您自己的过滤器类的调用,并且请求没有通过安全过滤器链(查看堆栈跟踪,那里)没有提到Spring Security过滤器)。因此,请求对象仍然是原始容器类型,而不是包装器。